# -*- coding: utf-8 -*- # # Copyright 2009 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Unit tests for fake_filesystem.FakeOpen.""" import errno import os import stat import sys import time import unittest from pyfakefs import fake_filesystem from pyfakefs.fake_filesystem import FakeFileOpen, is_root from pyfakefs.extra_packages import use_scandir, use_scandir_package from pyfakefs.tests.test_utils import DummyTime, TestCase, RealFsTestCase class FakeOsModuleTestBase(RealFsTestCase): def createTestFile(self, path): self.create_file(path) self.assertTrue(self.os.path.exists(path)) st = self.os.stat(path) self.assertEqual(0o666, stat.S_IMODE(st.st_mode)) self.assertTrue(st.st_mode & stat.S_IFREG) self.assertFalse(st.st_mode & stat.S_IFDIR) def createTestDirectory(self, path): self.create_dir(path) self.assertTrue(self.os.path.exists(path)) st = self.os.stat(path) self.assertEqual(0o777, stat.S_IMODE(st.st_mode)) self.assertFalse(st.st_mode & stat.S_IFREG) self.assertTrue(st.st_mode & stat.S_IFDIR) class FakeOsModuleTest(FakeOsModuleTestBase): def setUp(self): super(FakeOsModuleTest, self).setUp() self.rwx = self.os.R_OK | self.os.W_OK | self.os.X_OK self.rw = self.os.R_OK | self.os.W_OK def test_chdir(self): """chdir should work on a directory.""" directory = self.make_path('foo') self.create_dir(directory) self.os.chdir(directory) def test_chdir_fails_non_exist(self): """chdir should raise OSError if the target does not exist.""" directory = self.make_path('no', 'such', 'directory') self.assert_raises_os_error(errno.ENOENT, self.os.chdir, directory) def test_chdir_fails_non_directory(self): """chdir should raise OSError if the target is not a directory.""" filename = self.make_path('foo', 'bar') self.create_file(filename) self.assert_raises_os_error(self.not_dir_error(), self.os.chdir, filename) def test_consecutive_chdir(self): """Consecutive relative chdir calls should work.""" dir1 = self.make_path('foo') dir2 = 'bar' full_dirname = self.os.path.join(dir1, dir2) self.create_dir(full_dirname) self.os.chdir(dir1) self.os.chdir(dir2) # use real path to handle symlink /var to /private/var in MacOs self.assertEqual(os.path.realpath(self.os.getcwd()), os.path.realpath(full_dirname)) def test_backwards_chdir(self): """chdir into '..' should behave appropriately.""" # skipping real fs test - can't test root dir self.skip_real_fs() rootdir = self.os.getcwd() dirname = 'foo' abs_dirname = self.os.path.abspath(dirname) self.filesystem.create_dir(dirname) self.os.chdir(dirname) self.assertEqual(abs_dirname, self.os.getcwd()) self.os.chdir('..') self.assertEqual(rootdir, self.os.getcwd()) self.os.chdir(self.os.path.join(dirname, '..')) self.assertEqual(rootdir, self.os.getcwd()) def test_get_cwd(self): # skipping real fs test - can't test root dir self.skip_real_fs() dirname = self.make_path('foo', 'bar') self.create_dir(dirname) self.assertEqual(self.os.getcwd(), self.os.path.sep) self.os.chdir(dirname) self.assertEqual(self.os.getcwd(), dirname) def test_listdir(self): directory = self.make_path('xyzzy', 'plugh') files = ['foo', 'bar', 'baz'] for f in files: self.create_file(self.os.path.join(directory, f)) files.sort() self.assertEqual(files, sorted(self.os.listdir(directory))) @unittest.skipIf(sys.version_info < (3, 3), 'file descriptor as path new in Python 3.3') def test_listdir_uses_open_fd_as_path(self): self.check_posix_only() if os.listdir not in os.supports_fd: self.skip_real_fs() self.assert_raises_os_error(errno.EBADF, self.os.listdir, 500) dir_path = self.make_path('xyzzy', 'plugh') files = ['foo', 'bar', 'baz'] for f in files: self.create_file(self.os.path.join(dir_path, f)) files.sort() path_des = self.os.open(dir_path, os.O_RDONLY) self.assertEqual(files, sorted(self.os.listdir(path_des))) def test_listdir_returns_list(self): directory_root = self.make_path('xyzzy') self.os.mkdir(directory_root) directory = self.os.path.join(directory_root, 'bug') self.os.mkdir(directory) self.create_file(self.make_path(directory, 'foo')) self.assertEqual(['foo'], self.os.listdir(directory)) def test_listdir_on_symlink(self): self.skip_if_symlink_not_supported() directory = self.make_path('xyzzy') files = ['foo', 'bar', 'baz'] for f in files: self.create_file(self.make_path(directory, f)) self.create_symlink(self.make_path('symlink'), self.make_path('xyzzy')) files.sort() self.assertEqual(files, sorted(self.os.listdir(self.make_path('symlink')))) def test_listdir_error(self): file_path = self.make_path('foo', 'bar', 'baz') self.create_file(file_path) self.assert_raises_os_error(self.not_dir_error(), self.os.listdir, file_path) def test_exists_current_dir(self): self.assertTrue(self.os.path.exists('.')) def test_listdir_current(self): files = ['foo', 'bar', 'baz'] for f in files: self.create_file(self.make_path(f)) files.sort() self.assertEqual(files, sorted(self.os.listdir(self.base_path))) def test_fdopen(self): # under Windows and Python2, hangs in closing file self.skip_real_fs_failure(skip_posix=False, skip_python3=False) file_path1 = self.make_path('some_file1') self.create_file(file_path1, contents='contents here1') with self.open(file_path1, 'r') as fake_file1: fileno = fake_file1.fileno() fake_file2 = self.os.fdopen(fileno) self.assertNotEqual(fake_file2, fake_file1) self.assertRaises(TypeError, self.os.fdopen, None) self.assertRaises(TypeError, self.os.fdopen, 'a string') def test_out_of_range_fdopen(self): # test some file descriptor that is clearly out of range self.assert_raises_os_error(errno.EBADF, self.os.fdopen, 100) def test_closed_file_descriptor(self): # under Windows and Python2, hangs in tearDown self.skip_real_fs_failure(skip_posix=False, skip_python3=False) first_path = self.make_path('some_file1') second_path = self.make_path('some_file2') third_path = self.make_path('some_file3') self.create_file(first_path, contents='contents here1') self.create_file(second_path, contents='contents here2') self.create_file(third_path, contents='contents here3') fake_file1 = self.open(first_path, 'r') fake_file2 = self.open(second_path, 'r') fake_file3 = self.open(third_path, 'r') fileno1 = fake_file1.fileno() fileno2 = fake_file2.fileno() fileno3 = fake_file3.fileno() self.os.close(fileno2) self.assert_raises_os_error(errno.EBADF, self.os.close, fileno2) self.assertEqual(fileno1, fake_file1.fileno()) self.assertEqual(fileno3, fake_file3.fileno()) with self.os.fdopen(fileno1) as f: self.assertFalse(f is fake_file1) with self.os.fdopen(fileno3) as f: self.assertFalse(f is fake_file3) self.assert_raises_os_error(errno.EBADF, self.os.fdopen, fileno2) def test_fdopen_mode(self): self.skip_real_fs() file_path1 = self.make_path('some_file1') self.create_file(file_path1, contents='contents here1') self.os.chmod(file_path1, (stat.S_IFREG | 0o666) ^ stat.S_IWRITE) fake_file1 = self.open(file_path1, 'r') fileno1 = fake_file1.fileno() self.os.fdopen(fileno1) self.os.fdopen(fileno1, 'r') if not is_root(): exception = OSError if self.is_python2 else IOError self.assertRaises(exception, self.os.fdopen, fileno1, 'w') else: self.os.fdopen(fileno1, 'w') self.os.close(fileno1) def test_fstat(self): directory = self.make_path('xyzzy') file_path = self.os.path.join(directory, 'plugh') self.create_file(file_path, contents='ABCDE') with self.open(file_path) as file_obj: fileno = file_obj.fileno() self.assertTrue(stat.S_IFREG & self.os.fstat(fileno)[stat.ST_MODE]) self.assertTrue(stat.S_IFREG & self.os.fstat(fileno).st_mode) self.assertEqual(5, self.os.fstat(fileno)[stat.ST_SIZE]) def test_stat(self): directory = self.make_path('xyzzy') file_path = self.os.path.join(directory, 'plugh') self.create_file(file_path, contents='ABCDE') self.assertTrue(stat.S_IFDIR & self.os.stat(directory)[stat.ST_MODE]) self.assertTrue(stat.S_IFREG & self.os.stat(file_path)[stat.ST_MODE]) self.assertTrue(stat.S_IFREG & self.os.stat(file_path).st_mode) self.assertEqual(5, self.os.stat(file_path)[stat.ST_SIZE]) @unittest.skipIf(sys.version_info < (3, 3), 'file descriptor as path new in Python 3.3') def test_stat_uses_open_fd_as_path(self): self.skip_real_fs() self.assert_raises_os_error(errno.EBADF, self.os.stat, 5) file_path = self.make_path('foo', 'bar') self.create_file(file_path) with self.open(file_path) as f: self.assertTrue( stat.S_IFREG & self.os.stat(f.filedes)[stat.ST_MODE]) @unittest.skipIf(sys.version_info < (3, 3), 'follow_symlinks new in Python 3.3') def test_stat_no_follow_symlinks_posix(self): """Test that stat with follow_symlinks=False behaves like lstat.""" self.check_posix_only() directory = self.make_path('xyzzy') base_name = 'plugh' file_contents = 'frobozz' # Just make sure we didn't accidentally make our test data meaningless. self.assertNotEqual(len(base_name), len(file_contents)) file_path = self.os.path.join(directory, base_name) link_path = self.os.path.join(directory, 'link') self.create_file(file_path, contents=file_contents) self.create_symlink(link_path, base_name) self.assertEqual(len(file_contents), self.os.stat(file_path, follow_symlinks=False)[ stat.ST_SIZE]) self.assertEqual(len(base_name), self.os.stat(link_path, follow_symlinks=False)[ stat.ST_SIZE]) @unittest.skipIf(sys.version_info < (3, 3), 'follow_symlinks new in Python 3.3') def test_stat_no_follow_symlinks_windows(self): """Test that stat with follow_symlinks=False behaves like lstat.""" self.check_windows_only() self.skip_if_symlink_not_supported() directory = self.make_path('xyzzy') base_name = 'plugh' file_contents = 'frobozz' # Just make sure we didn't accidentally make our test data meaningless. self.assertNotEqual(len(base_name), len(file_contents)) file_path = self.os.path.join(directory, base_name) link_path = self.os.path.join(directory, 'link') self.create_file(file_path, contents=file_contents) self.create_symlink(link_path, base_name) self.assertEqual(len(file_contents), self.os.stat(file_path, follow_symlinks=False)[ stat.ST_SIZE]) self.assertEqual(0, self.os.stat(link_path, follow_symlinks=False)[ stat.ST_SIZE]) def test_lstat_size_posix(self): self.check_posix_only() directory = self.make_path('xyzzy') base_name = 'plugh' file_contents = 'frobozz' # Just make sure we didn't accidentally make our test data meaningless. self.assertNotEqual(len(base_name), len(file_contents)) file_path = self.os.path.join(directory, base_name) link_path = self.os.path.join(directory, 'link') self.create_file(file_path, contents=file_contents) self.create_symlink(link_path, base_name) self.assertEqual(len(file_contents), self.os.lstat(file_path)[stat.ST_SIZE]) self.assertEqual(len(base_name), self.os.lstat(link_path)[stat.ST_SIZE]) def test_lstat_size_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() directory = self.make_path('xyzzy') base_name = 'plugh' file_contents = 'frobozz' # Just make sure we didn't accidentally make our test data meaningless. self.assertNotEqual(len(base_name), len(file_contents)) file_path = self.os.path.join(directory, base_name) link_path = self.os.path.join(directory, 'link') self.create_file(file_path, contents=file_contents) self.create_symlink(link_path, base_name) self.assertEqual(len(file_contents), self.os.lstat(file_path)[stat.ST_SIZE]) self.assertEqual(0, self.os.lstat(link_path)[stat.ST_SIZE]) def test_lstat_trailing_sep(self): # regression test for #342 stat = self.os.lstat(self.base_path) self.assertEqual(stat, self.os.lstat(self.base_path + self.path_separator())) self.assertEqual(stat, self.os.lstat( self.base_path + self.path_separator() + self.path_separator())) def test_exists_with_trailing_sep(self): # regression test for #364 file_path = self.make_path('alpha') self.create_file(file_path) self.assertFalse(self.os.path.exists(file_path + self.os.sep)) def test_mkdir_with_trailing_sep(self): # regression test for #367 dir_path = self.make_path('foo') self.os.mkdir(dir_path + self.os.sep + self.os.sep) self.assertTrue(self.os.path.exists(dir_path)) def test_readlink_ending_with_sep_posix(self): # regression test for #359 self.check_posix_only() link_path = self.make_path('foo') self.os.symlink(self.base_path, link_path) self.assert_raises_os_error(errno.EINVAL, self.os.readlink, link_path + self.os.sep) def test_lstat_symlink_with_trailing_sep_linux(self): # regression test for #366 self.check_linux_only() self.skip_if_symlink_not_supported() link_path = self.make_path('foo') self.os.symlink(self.base_path, link_path) # used to raise self.assertTrue(self.os.lstat(link_path + self.os.sep).st_mode) def test_lstat_symlink_with_trailing_sep_macos(self): # regression test for #366 self.check_macos_only() self.skip_if_symlink_not_supported() link_path = self.make_path('foo') self.os.symlink(self.base_path, link_path) # used to raise self.assertTrue(self.os.lstat(link_path + self.os.sep).st_mode) def test_readlink_ending_with_sep_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() link_path = self.make_path('foo') self.os.symlink(self.base_path, link_path) self.assertEqual(self.base_path, self.os.readlink(link_path + self.os.sep)) def test_islink_with_trailing_sep_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() link_path = self.make_path('foo') self.os.symlink(self.base_path, link_path) self.assertTrue(self.os.path.islink(link_path + self.os.path.sep)) def test_islink_with_trailing_sep_linux(self): self.check_linux_only() link_path = self.make_path('foo') self.os.symlink(self.base_path, link_path) self.assertFalse(self.os.path.islink(link_path + self.os.sep)) def test_islink_with_trailing_sep_macos(self): self.check_macos_only() link_path = self.make_path('foo') self.os.symlink(self.base_path, link_path) self.assertFalse(self.os.path.islink(link_path + self.os.sep)) def check_getsize_raises_with_trailing_separator(self, error_nr): file_path = self.make_path('bar') self.create_file(file_path) self.assert_raises_os_error(error_nr, self.os.path.getsize, file_path + self.os.sep) def test_getsize_raises_with_trailing_separator_posix(self): self.check_posix_only() self.check_getsize_raises_with_trailing_separator(errno.ENOTDIR) def test_getsize_raises_with_trailing_separator_windows(self): self.check_windows_only() self.check_getsize_raises_with_trailing_separator(errno.EINVAL) def check_remove_link_ending_with_sep(self, error_nr): # regression test for #360 link_path = self.make_path('foo') self.os.symlink(self.base_path, link_path) self.assert_raises_os_error(error_nr, self.os.remove, link_path + self.os.sep) def test_remove_link_ending_with_sep_linux(self): self.check_linux_only() self.check_remove_link_ending_with_sep(errno.ENOTDIR) def test_remove_link_ending_with_sep_macos(self): self.check_macos_only() self.check_remove_link_ending_with_sep(errno.EPERM) def test_remove_link_ending_with_sep_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() self.check_remove_link_ending_with_sep(errno.EACCES) @unittest.skipIf(sys.version_info < (3, 3), 'file descriptor as path new in Python 3.3') def test_lstat_uses_open_fd_as_path(self): self.skip_if_symlink_not_supported() if os.lstat not in os.supports_fd: self.skip_real_fs() self.assert_raises_os_error(errno.EBADF, self.os.lstat, 5) file_path = self.make_path('foo', 'bar') link_path = self.make_path('foo', 'link') file_contents = b'contents' self.create_file(file_path, contents=file_contents) self.create_symlink(link_path, file_path) with self.open(file_path) as f: self.assertEqual(len(file_contents), self.os.lstat(f.filedes)[stat.ST_SIZE]) def test_stat_non_existent_file(self): # set up file_path = self.make_path('non', 'existent', 'file') self.assertFalse(self.os.path.exists(file_path)) # actual tests try: # Use try-catch to check exception attributes. self.os.stat(file_path) self.fail('Exception is expected.') # COV_NF_LINE except OSError as os_error: self.assertEqual(errno.ENOENT, os_error.errno) self.assertEqual(file_path, os_error.filename) def check_open_raises_with_trailing_separator(self, error_nr): file_path = self.make_path('bar') + self.os.sep self.assert_raises_os_error(error_nr, self.os.open, file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) def test_open_raises_with_trailing_separator_linux(self): self.check_linux_only() self.check_open_raises_with_trailing_separator(errno.EISDIR) def test_open_raises_with_trailing_separator_macos(self): self.check_macos_only() self.check_open_raises_with_trailing_separator(errno.ENOENT) def test_open_raises_with_trailing_separator_windows(self): self.check_windows_only() self.check_open_raises_with_trailing_separator(errno.EINVAL) def test_lexists_with_trailing_separator_linux_windows(self): self.check_linux_and_windows() self.skip_if_symlink_not_supported() file_path = self.make_path('foo') self.os.symlink(file_path, file_path) self.assertFalse(self.os.path.lexists(file_path + self.os.sep)) def test_lexists_with_trailing_separator_macos(self): # regression test for #373 self.check_macos_only() file_path = self.make_path('foo') self.os.symlink(file_path, file_path) self.assertTrue(self.os.path.lexists(file_path + self.os.sep)) def test_islink_with_trailing_separator_linux_windows(self): self.check_linux_and_windows() self.skip_if_symlink_not_supported() file_path = self.make_path('foo') self.os.symlink(file_path, file_path) self.assertFalse(self.os.path.islink(file_path + self.os.sep)) def test_islink_with_trailing_separator_macos(self): # regression test for #373 self.check_macos_only() file_path = self.make_path('foo') self.os.symlink(file_path, file_path) self.assertTrue(self.os.path.islink(file_path + self.os.sep)) def test_isfile_with_trailing_separator_linux_windows(self): self.check_linux_and_windows() file_path = self.make_path('foo') self.create_file(file_path) self.assertFalse(self.os.path.isfile(file_path + self.os.sep)) def test_isfile_with_trailing_separator_macos(self): # regression test for #374 self.check_macos_only() file_path = self.make_path('foo') self.create_file(file_path) self.assertFalse(self.os.path.isfile(file_path + self.os.sep)) def check_stat_with_trailing_separator(self, error_nr): # regression test for #376 file_path = self.make_path('foo') self.create_file(file_path) self.assert_raises_os_error(error_nr, self.os.stat, file_path + self.os.sep) def test_stat_with_trailing_separator_posix(self): self.check_posix_only() self.check_stat_with_trailing_separator(errno.ENOTDIR) def test_stat_with_trailing_separator_windows(self): self.check_windows_only() self.check_stat_with_trailing_separator(errno.EINVAL) def check_remove_with_trailing_separator(self, error_nr): # regression test for #377 file_path = self.make_path('foo') self.create_file(file_path) self.assert_raises_os_error(error_nr, self.os.remove, file_path + self.os.sep) def test_remove_with_trailing_separator_posix(self): self.check_posix_only() self.check_remove_with_trailing_separator(errno.ENOTDIR) def test_remove_with_trailing_separator_windows(self): self.check_windows_only() self.check_remove_with_trailing_separator(errno.EINVAL) def test_readlink(self): self.skip_if_symlink_not_supported() link_path = self.make_path('foo', 'bar', 'baz') target = self.make_path('tarJAY') self.create_symlink(link_path, target) self.assertEqual(self.os.readlink(link_path), target) def check_readlink_raises_if_path_is_not_a_link(self): file_path = self.make_path('foo', 'bar', 'eleventyone') self.create_file(file_path) self.assert_raises_os_error(errno.EINVAL, self.os.readlink, file_path) def test_readlink_raises_if_path_is_not_a_link_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() self.check_readlink_raises_if_path_is_not_a_link() def test_readlink_raises_if_path_is_not_a_link_posix(self): self.check_posix_only() self.check_readlink_raises_if_path_is_not_a_link() def check_readlink_raises_if_path_has_file(self, error_subtype): self.create_file(self.make_path('a_file')) file_path = self.make_path('a_file', 'foo') self.assert_raises_os_error(error_subtype, self.os.readlink, file_path) file_path = self.make_path('a_file', 'foo', 'bar') self.assert_raises_os_error(error_subtype, self.os.readlink, file_path) def test_readlink_raises_if_path_has_file_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() self.check_readlink_raises_if_path_has_file(errno.ENOENT) def test_readlink_raises_if_path_has_file_posix(self): self.check_posix_only() self.check_readlink_raises_if_path_has_file(errno.ENOTDIR) def test_readlink_raises_if_path_does_not_exist(self): self.skip_if_symlink_not_supported() self.assert_raises_os_error(errno.ENOENT, self.os.readlink, '/this/path/does/not/exist') def test_readlink_raises_if_path_is_none(self): self.skip_if_symlink_not_supported() self.assertRaises(TypeError, self.os.readlink, None) def test_broken_symlink_with_trailing_separator_linux(self): self.check_linux_only() file_path = self.make_path('foo') link_path = self.make_path('link') self.os.symlink(file_path, link_path) self.assert_raises_os_error(errno.EEXIST, self.os.symlink, link_path + self.os.sep, link_path + self.os.sep) def test_broken_symlink_with_trailing_separator_macos(self): # regression test for #371 self.check_macos_only() file_path = self.make_path('foo') link_path = self.make_path('link') self.os.symlink(file_path, link_path) self.os.symlink(link_path + self.os.sep, link_path + self.os.sep) def test_broken_symlink_with_trailing_separator_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() file_path = self.make_path('foo') link_path = self.make_path('link') self.os.symlink(file_path, link_path) self.assert_raises_os_error(errno.EINVAL, self.os.symlink, link_path + self.os.sep, link_path + self.os.sep) def test_circular_readlink_with_trailing_separator_linux(self): # Regression test for #372 self.check_linux_only() file_path = self.make_path('foo') self.os.symlink(file_path, file_path) self.assert_raises_os_error(errno.ELOOP, self.os.readlink, file_path + self.os.sep) def test_circular_readlink_with_trailing_separator_macos(self): # Regression test for #372 self.check_macos_only() file_path = self.make_path('foo') self.os.symlink(file_path, file_path) self.os.readlink(file_path + self.os.sep) def test_circular_readlink_with_trailing_separator_windows(self): # Regression test for #372 self.check_windows_only() self.skip_if_symlink_not_supported() file_path = self.make_path('foo') self.os.symlink(file_path, file_path) self.assert_raises_os_error(errno.EINVAL, self.os.readlink, file_path + self.os.sep) def test_readlink_with_links_in_path(self): self.skip_if_symlink_not_supported() self.create_symlink(self.make_path('meyer', 'lemon', 'pie'), self.make_path('yum')) self.create_symlink(self.make_path('geo', 'metro'), self.make_path('meyer')) self.assertEqual(self.make_path('yum'), self.os.readlink( self.make_path('geo', 'metro', 'lemon', 'pie'))) def test_readlink_with_chained_links_in_path(self): self.skip_if_symlink_not_supported() self.create_symlink(self.make_path( 'eastern', 'european', 'wolfhounds', 'chase'), self.make_path('cats')) self.create_symlink(self.make_path('russian'), self.make_path('eastern', 'european')) self.create_symlink(self.make_path('dogs'), self.make_path('russian', 'wolfhounds')) self.assertEqual(self.make_path('cats'), self.os.readlink(self.make_path('dogs', 'chase'))) def check_remove_dir(self, dir_error): directory = self.make_path('xyzzy') dir_path = self.os.path.join(directory, 'plugh') self.create_dir(dir_path) self.assertTrue(self.os.path.exists(dir_path)) self.assert_raises_os_error(dir_error, self.os.remove, dir_path) self.assertTrue(self.os.path.exists(dir_path)) self.os.chdir(directory) self.assert_raises_os_error(dir_error, self.os.remove, dir_path) self.assertTrue(self.os.path.exists(dir_path)) self.assert_raises_os_error(errno.ENOENT, self.os.remove, '/plugh') def test_remove_dir_linux(self): self.check_linux_only() self.check_remove_dir(errno.EISDIR) def test_remove_dir_mac_os(self): self.check_macos_only() self.check_remove_dir(errno.EPERM) def test_remove_dir_windows(self): self.check_windows_only() self.check_remove_dir(errno.EACCES) def test_remove_dir_with_drive(self): # regression test for issue #337 self.check_windows_only() self.skip_real_fs() dir_path = self.os.path.join('C:', 'test') self.filesystem.create_dir(dir_path) self.assert_raises_os_error(errno.EACCES, self.os.remove, dir_path) def test_remove_file(self): directory = self.make_path('zzy') file_path = self.os.path.join(directory, 'plugh') self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.os.remove(file_path) self.assertFalse(self.os.path.exists(file_path)) def test_remove_file_no_directory(self): directory = self.make_path('zzy') file_name = 'plugh' file_path = self.os.path.join(directory, file_name) self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.os.chdir(directory) self.os.remove(file_name) self.assertFalse(self.os.path.exists(file_path)) def test_remove_file_with_read_permission_raises_in_windows(self): self.check_windows_only() path = self.make_path('foo', 'bar') self.create_file(path) self.os.chmod(path, 0o444) self.assert_raises_os_error(errno.EACCES, self.os.remove, path) self.os.chmod(path, 0o666) def test_remove_file_with_read_permission_shall_succeed_in_posix(self): self.check_posix_only() path = self.make_path('foo', 'bar') self.create_file(path) self.os.chmod(path, 0o444) self.os.remove(path) self.assertFalse(self.os.path.exists(path)) def test_remove_file_without_parent_permission_raises_in_posix(self): self.check_posix_only() parent_dir = self.make_path('foo') path = self.os.path.join(parent_dir, 'bar') self.create_file(path) self.os.chmod(parent_dir, 0o666) # missing execute permission if not is_root(): self.assert_raises_os_error(errno.EACCES, self.os.remove, path) else: self.os.remove(path) self.assertFalse(self.os.path.exists(path)) self.create_file(path) self.os.chmod(parent_dir, 0o555) # missing write permission if not is_root(): self.assert_raises_os_error(errno.EACCES, self.os.remove, path) else: self.os.remove(path) self.assertFalse(self.os.path.exists(path)) self.create_file(path) self.os.chmod(parent_dir, 0o333) self.os.remove(path) self.assertFalse(self.os.path.exists(path)) def test_remove_open_file_fails_under_windows(self): self.check_windows_only() path = self.make_path('foo', 'bar') self.create_file(path) with self.open(path, 'r'): self.assert_raises_os_error(errno.EACCES, self.os.remove, path) self.assertTrue(self.os.path.exists(path)) def test_remove_open_file_possible_under_posix(self): self.check_posix_only() path = self.make_path('foo', 'bar') self.create_file(path) self.open(path, 'r') self.os.remove(path) self.assertFalse(self.os.path.exists(path)) def test_remove_file_relative_path(self): self.skip_real_fs() original_dir = self.os.getcwd() directory = self.make_path('zzy') subdirectory = self.os.path.join(directory, 'zzy') file_name = 'plugh' file_path = self.os.path.join(directory, file_name) file_path_relative = self.os.path.join('..', file_name) self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.create_dir(subdirectory) self.assertTrue(self.os.path.exists(subdirectory)) self.os.chdir(subdirectory) self.os.remove(file_path_relative) self.assertFalse(self.os.path.exists(file_path_relative)) self.os.chdir(original_dir) self.assertFalse(self.os.path.exists(file_path)) def check_remove_dir_raises_error(self, dir_error): directory = self.make_path('zzy') self.create_dir(directory) self.assert_raises_os_error(dir_error, self.os.remove, directory) def test_remove_dir_raises_error_linux(self): self.check_linux_only() self.check_remove_dir_raises_error(errno.EISDIR) def test_remove_dir_raises_error_mac_os(self): self.check_macos_only() self.check_remove_dir_raises_error(errno.EPERM) def test_remove_dir_raises_error_windows(self): self.check_windows_only() self.check_remove_dir_raises_error(errno.EACCES) def test_remove_symlink_to_dir(self): self.skip_if_symlink_not_supported() directory = self.make_path('zzy') link = self.make_path('link_to_dir') self.create_dir(directory) self.os.symlink(directory, link) self.assertTrue(self.os.path.exists(directory)) self.assertTrue(self.os.path.exists(link)) self.os.remove(link) self.assertTrue(self.os.path.exists(directory)) self.assertFalse(self.os.path.exists(link)) def test_unlink_raises_if_not_exist(self): file_path = self.make_path('file', 'does', 'not', 'exist') self.assertFalse(self.os.path.exists(file_path)) self.assert_raises_os_error(errno.ENOENT, self.os.unlink, file_path) def test_rename_to_nonexistent_file(self): """Can rename a file to an unused name.""" directory = self.make_path('xyzzy') old_file_path = self.os.path.join(directory, 'plugh_old') new_file_path = self.os.path.join(directory, 'plugh_new') self.create_file(old_file_path, contents='test contents') self.assertTrue(self.os.path.exists(old_file_path)) self.assertFalse(self.os.path.exists(new_file_path)) self.os.rename(old_file_path, new_file_path) self.assertFalse(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.check_contents(new_file_path, 'test contents') def test_rename_dir_to_symlink_posix(self): self.check_posix_only() link_path = self.make_path('link') dir_path = self.make_path('dir') link_target = self.os.path.join(dir_path, 'link_target') self.create_dir(dir_path) self.os.symlink(link_target, link_path) self.assert_raises_os_error(errno.ENOTDIR, self.os.rename, dir_path, link_path) def test_rename_dir_to_symlink_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() link_path = self.make_path('link') dir_path = self.make_path('dir') link_target = self.os.path.join(dir_path, 'link_target') self.create_dir(dir_path) self.os.symlink(link_target, link_path) self.assert_raises_os_error(errno.EEXIST, self.os.rename, dir_path, link_path) def test_rename_file_to_symlink(self): self.check_posix_only() link_path = self.make_path('file_link') file_path = self.make_path('file') self.os.symlink(file_path, link_path) self.create_file(file_path) self.os.rename(file_path, link_path) self.assertFalse(self.os.path.exists(file_path)) self.assertTrue(self.os.path.exists(link_path)) self.assertTrue(self.os.path.isfile(link_path)) def test_rename_symlink_to_symlink(self): self.check_posix_only() base_path = self.make_path('foo', 'bar') self.create_dir(base_path) link_path1 = self.os.path.join(base_path, 'link1') link_path2 = self.os.path.join(base_path, 'link2') self.os.symlink(base_path, link_path1) self.os.symlink(base_path, link_path2) self.os.rename(link_path1, link_path2) self.assertFalse(self.os.path.exists(link_path1)) self.assertTrue(self.os.path.exists(link_path2)) def test_rename_symlink_to_symlink_for_parent_raises(self): self.check_posix_only() dir_link = self.make_path('dir_link') dir_path = self.make_path('dir') dir_in_dir_path = self.os.path.join(dir_link, 'inner_dir') self.create_dir(dir_path) self.os.symlink(dir_path, dir_link) self.create_dir(dir_in_dir_path) self.assert_raises_os_error(errno.EINVAL, self.os.rename, dir_path, dir_in_dir_path) def check_rename_case_with_symlink(self, result): self.skip_if_symlink_not_supported() self.check_case_insensitive_fs() dir_path_lower = self.make_path('beta') self.create_dir(dir_path_lower) link_path = self.make_path('b') self.os.symlink(self.base_path, link_path) path1 = self.os.path.join(link_path, 'Beta') dir_path_upper = self.make_path('Beta') self.os.rename(path1, dir_path_upper) self.assertEqual(result, sorted(self.os.listdir(self.base_path))) def test_rename_case_with_symlink_mac(self): # Regression test for #322 self.check_macos_only() self.check_rename_case_with_symlink(['b', 'beta']) def test_rename_case_with_symlink_windows(self): self.check_windows_only() self.check_rename_case_with_symlink(['Beta', 'b']) def test_recursive_rename_raises(self): self.check_posix_only() base_path = self.make_path('foo', 'bar') self.create_dir(base_path) new_path = self.os.path.join(base_path, 'new_dir') self.assert_raises_os_error(errno.EINVAL, self.os.rename, base_path, new_path) def test_rename_file_to_parent_dir_file(self): # Regression test for issue 230 dir_path = self.make_path('dir') self.create_dir(dir_path) file_path = self.make_path('old_file') new_file_path = self.os.path.join(dir_path, 'new_file') self.create_file(file_path) self.os.rename(file_path, new_file_path) def test_rename_with_target_parent_file_raises_posix(self): self.check_posix_only() file_path = self.make_path('foo', 'baz') self.create_file(file_path) self.assert_raises_os_error(errno.ENOTDIR, self.os.rename, file_path, file_path + '/new') def test_rename_with_target_parent_file_raises_windows(self): self.check_windows_only() file_path = self.make_path('foo', 'baz') self.create_file(file_path) self.assert_raises_os_error(errno.EACCES, self.os.rename, file_path, self.os.path.join(file_path, 'new')) def test_rename_symlink_to_source(self): self.check_posix_only() base_path = self.make_path('foo') link_path = self.os.path.join(base_path, 'slink') file_path = self.os.path.join(base_path, 'file') self.create_file(file_path) self.os.symlink(file_path, link_path) self.os.rename(link_path, file_path) self.assertFalse(self.os.path.exists(file_path)) def test_rename_symlink_to_dir_raises(self): self.check_posix_only() base_path = self.make_path('foo', 'bar') link_path = self.os.path.join(base_path, 'dir_link') dir_path = self.os.path.join(base_path, 'dir') self.create_dir(dir_path) self.os.symlink(dir_path, link_path) self.assert_raises_os_error(errno.EISDIR, self.os.rename, link_path, dir_path) def test_rename_broken_symlink(self): self.check_posix_only() base_path = self.make_path('foo') self.create_dir(base_path) link_path = self.os.path.join(base_path, 'slink') file_path = self.os.path.join(base_path, 'file') self.os.symlink(file_path, link_path) self.os.rename(link_path, file_path) self.assertFalse(self.os.path.exists(file_path)) self.assertTrue(self.os.path.lexists(file_path)) self.assertFalse(self.os.path.exists(link_path)) def test_rename_directory(self): """Can rename a directory to an unused name.""" for old_path, new_path in [('wxyyw', 'xyzzy'), ('abccb', 'cdeed')]: old_path = self.make_path(old_path) new_path = self.make_path(new_path) self.create_file(self.os.path.join(old_path, 'plugh'), contents='test') self.assertTrue(self.os.path.exists(old_path)) self.assertFalse(self.os.path.exists(new_path)) self.os.rename(old_path, new_path) self.assertFalse(self.os.path.exists(old_path)) self.assertTrue(self.os.path.exists(new_path)) self.check_contents(self.os.path.join(new_path, 'plugh'), 'test') if not self.use_real_fs(): self.assertEqual(3, self.filesystem.get_object(new_path).st_nlink) def check_rename_directory_to_existing_file_raises(self, error_nr): dir_path = self.make_path('dir') file_path = self.make_path('file') self.create_dir(dir_path) self.create_file(file_path) self.assert_raises_os_error(error_nr, self.os.rename, dir_path, file_path) def test_rename_directory_to_existing_file_raises_posix(self): self.check_posix_only() self.check_rename_directory_to_existing_file_raises(errno.ENOTDIR) def test_rename_directory_to_existing_file_raises_windows(self): self.check_windows_only() self.check_rename_directory_to_existing_file_raises(errno.EEXIST) def test_rename_to_existing_directory_should_raise_under_windows(self): """Renaming to an existing directory raises OSError under Windows.""" self.check_windows_only() old_path = self.make_path('foo', 'bar') new_path = self.make_path('foo', 'baz') self.create_dir(old_path) self.create_dir(new_path) self.assert_raises_os_error(errno.EEXIST, self.os.rename, old_path, new_path) def test_rename_to_a_hardlink_of_same_file_should_do_nothing(self): self.skip_real_fs_failure(skip_posix=False) self.skip_if_symlink_not_supported() file_path = self.make_path('dir', 'file') self.create_file(file_path) link_path = self.make_path('link') self.os.link(file_path, link_path) self.os.rename(file_path, link_path) self.assertTrue(self.os.path.exists(file_path)) self.assertTrue(self.os.path.exists(link_path)) def test_hardlink_works_with_symlink(self): self.check_posix_only() base_path = self.make_path('foo') self.create_dir(base_path) symlink_path = self.os.path.join(base_path, 'slink') self.os.symlink(base_path, symlink_path) file_path = self.os.path.join(base_path, 'slink', 'beta') self.create_file(file_path) link_path = self.os.path.join(base_path, 'slink', 'gamma') self.os.link(file_path, link_path) self.assertTrue(self.os.path.exists(link_path)) @unittest.skipIf(sys.version_info < (3, 3), 'replace is new in Python 3.3') def test_replace_existing_directory_should_raise_under_windows(self): """Renaming to an existing directory raises OSError under Windows.""" self.check_windows_only() old_path = self.make_path('foo', 'bar') new_path = self.make_path('foo', 'baz') self.create_dir(old_path) self.create_dir(new_path) self.assert_raises_os_error(errno.EACCES, self.os.replace, old_path, new_path) def test_rename_to_existing_directory_under_posix(self): """Renaming to an existing directory changes the existing directory under Posix.""" self.check_posix_only() old_path = self.make_path('foo', 'bar') new_path = self.make_path('xyzzy') self.create_dir(self.os.path.join(old_path, 'sub')) self.create_dir(new_path) self.os.rename(old_path, new_path) self.assertTrue( self.os.path.exists(self.os.path.join(new_path, 'sub'))) self.assertFalse(self.os.path.exists(old_path)) def test_rename_file_to_existing_directory_raises_under_posix(self): self.check_posix_only() file_path = self.make_path('foo', 'bar', 'baz') new_path = self.make_path('xyzzy') self.create_file(file_path) self.create_dir(new_path) self.assert_raises_os_error(errno.EISDIR, self.os.rename, file_path, new_path) def test_rename_to_existing_dir_under_posix_raises_if_not_empty(self): """Renaming to an existing directory changes the existing directory under Posix.""" self.check_posix_only() old_path = self.make_path('foo', 'bar') new_path = self.make_path('foo', 'baz') self.create_dir(self.os.path.join(old_path, 'sub')) self.create_dir(self.os.path.join(new_path, 'sub')) # not testing specific subtype: # raises errno.ENOTEMPTY under Ubuntu 16.04, MacOS and pyfakefs # but raises errno.EEXIST at least under Ubunto 14.04 self.assertRaises(OSError, self.os.rename, old_path, new_path) def test_rename_to_another_device_should_raise(self): """Renaming to another filesystem device raises OSError.""" self.skip_real_fs() self.filesystem.add_mount_point('/mount') old_path = '/foo/bar' new_path = '/mount/bar' self.filesystem.create_file(old_path) self.assert_raises_os_error(errno.EXDEV, self.os.rename, old_path, new_path) def test_rename_to_existent_file_posix(self): """Can rename a file to a used name under Unix.""" self.check_posix_only() directory = self.make_path('xyzzy') old_file_path = self.os.path.join(directory, 'plugh_old') new_file_path = self.os.path.join(directory, 'plugh_new') self.create_file(old_file_path, contents='test contents 1') self.create_file(new_file_path, contents='test contents 2') self.assertTrue(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.os.rename(old_file_path, new_file_path) self.assertFalse(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.check_contents(new_file_path, 'test contents 1') def test_rename_to_existent_file_windows(self): """Renaming a file to a used name raises OSError under Windows.""" self.check_windows_only() directory = self.make_path('xyzzy') old_file_path = self.os.path.join(directory, 'plugh_old') new_file_path = self.os.path.join(directory, 'plugh_new') self.create_file(old_file_path, contents='test contents 1') self.create_file(new_file_path, contents='test contents 2') self.assertTrue(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.assert_raises_os_error( errno.EEXIST, self.os.rename, old_file_path, new_file_path) @unittest.skipIf(sys.version_info < (3, 3), 'replace is new in Python 3.3') def test_replace_to_existent_file(self): """Replaces an existing file (does not work with `rename()` under Windows).""" directory = self.make_path('xyzzy') old_file_path = self.os.path.join(directory, 'plugh_old') new_file_path = self.os.path.join(directory, 'plugh_new') self.create_file(old_file_path, contents='test contents 1') self.create_file(new_file_path, contents='test contents 2') self.assertTrue(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.os.replace(old_file_path, new_file_path) self.assertFalse(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.check_contents(new_file_path, 'test contents 1') def test_rename_to_nonexistent_dir(self): """Can rename a file to a name in a nonexistent dir.""" directory = self.make_path('xyzzy') old_file_path = self.os.path.join(directory, 'plugh_old') new_file_path = self.os.path.join( directory, 'no_such_path', 'plugh_new') self.create_file(old_file_path, contents='test contents') self.assertTrue(self.os.path.exists(old_file_path)) self.assertFalse(self.os.path.exists(new_file_path)) self.assert_raises_os_error( errno.ENOENT, self.os.rename, old_file_path, new_file_path) self.assertTrue(self.os.path.exists(old_file_path)) self.assertFalse(self.os.path.exists(new_file_path)) self.check_contents(old_file_path, 'test contents') def test_rename_nonexistent_file_should_raise_error(self): """Can't rename a file that doesn't exist.""" self.assert_raises_os_error(errno.ENOENT, self.os.rename, 'nonexistent-foo', 'doesn\'t-matter-bar') def test_rename_empty_dir(self): """Test a rename of an empty directory.""" directory = self.make_path('xyzzy') before_dir = self.os.path.join(directory, 'empty') after_dir = self.os.path.join(directory, 'unused') self.create_dir(before_dir) self.assertTrue( self.os.path.exists(self.os.path.join(before_dir, '.'))) self.assertFalse(self.os.path.exists(after_dir)) self.os.rename(before_dir, after_dir) self.assertFalse(self.os.path.exists(before_dir)) self.assertTrue(self.os.path.exists(self.os.path.join(after_dir, '.'))) def test_rename_symlink(self): self.check_posix_only() base_path = self.make_path('foo', 'bar') self.create_dir(base_path) link_path = self.os.path.join(base_path, 'link') self.os.symlink(base_path, link_path) file_path = self.os.path.join(link_path, 'file') new_file_path = self.os.path.join(link_path, 'new') self.create_file(file_path) self.os.rename(file_path, new_file_path) self.assertFalse(self.os.path.exists(file_path)) self.assertTrue(self.os.path.exists(new_file_path)) def check_append_mode_tell_after_truncate(self, tell_result): file_path = self.make_path('baz') with self.open(file_path, 'w') as f0: with self.open(file_path, 'a') as f1: f1.write('abcde') f0.seek(2) f0.truncate() self.assertEqual(tell_result, f1.tell()) with self.open(file_path, mode='rb') as f: self.assertEqual(b'\0\0abcde', f.read()) def test_append_mode_tell_linux_windows(self): # Regression test for #300 self.check_linux_and_windows() tell_result = 5 if self.is_python2 else 7 self.check_append_mode_tell_after_truncate(tell_result) def test_append_mode_tell_macos(self): # Regression test for #300 self.check_macos_only() self.check_append_mode_tell_after_truncate(7) def test_tell_after_seek_in_append_mode(self): # Regression test for #363 file_path = self.make_path('foo') with self.open(file_path, 'a') as f: f.seek(1) self.assertEqual(1, f.tell()) def test_tell_after_seekback_in_append_mode(self): # Regression test for #414 file_path = self.make_path('foo') with self.open(file_path, 'a') as f: f.write('aa') f.seek(1) self.assertEqual(1, f.tell()) def test_dir_with_trailing_sep_is_dir(self): # regression test for #387 self.assertTrue(self, self.os.path.isdir(self.base_path + self.os.sep)) def check_rename_dir_with_trailing_sep(self, error): dir_path = self.make_path('dir') + self.os.sep self.os.mkdir(dir_path) self.assert_raises_os_error(error, self.os.rename, dir_path, self.base_path) def test_rename_dir_with_trailing_sep_posix(self): # regression test for #406 self.check_posix_only() self.check_rename_dir_with_trailing_sep(errno.ENOTEMPTY) def test_rename_dir_with_trailing_sep_windows(self): self.check_windows_only() self.check_rename_dir_with_trailing_sep(errno.EEXIST) def test_rename_dir(self): """Test a rename of a directory.""" directory = self.make_path('xyzzy') before_dir = self.os.path.join(directory, 'before') before_file = self.os.path.join(directory, 'before', 'file') after_dir = self.os.path.join(directory, 'after') after_file = self.os.path.join(directory, 'after', 'file') self.create_dir(before_dir) self.create_file(before_file, contents='payload') self.assertTrue(self.os.path.exists(before_dir)) self.assertTrue(self.os.path.exists(before_file)) self.assertFalse(self.os.path.exists(after_dir)) self.assertFalse(self.os.path.exists(after_file)) self.os.rename(before_dir, after_dir) self.assertFalse(self.os.path.exists(before_dir)) self.assertFalse(self.os.path.exists(before_file)) self.assertTrue(self.os.path.exists(after_dir)) self.assertTrue(self.os.path.exists(after_file)) self.check_contents(after_file, 'payload') def test_rename_preserves_stat(self): """Test if rename preserves mtime.""" self.check_posix_only() self.skip_real_fs() directory = self.make_path('xyzzy') old_file_path = self.os.path.join(directory, 'plugh_old') new_file_path = self.os.path.join(directory, 'plugh_new') self.create_file(old_file_path) old_file = self.filesystem.get_object(old_file_path) old_file.st_mtime = old_file.st_mtime - 3600 self.os.chown(old_file_path, 200, 200) self.os.chmod(old_file_path, 0o222) self.create_file(new_file_path) new_file = self.filesystem.get_object(new_file_path) self.assertNotEqual(new_file.st_mtime, old_file.st_mtime) self.os.rename(old_file_path, new_file_path) new_file = self.filesystem.get_object(new_file_path) self.assertEqual(new_file.st_mtime, old_file.st_mtime) self.assertEqual(new_file.st_mode, old_file.st_mode) self.assertEqual(new_file.st_uid, old_file.st_uid) self.assertEqual(new_file.st_gid, old_file.st_gid) def test_rename_same_filenames(self): """Test renaming when old and new names are the same.""" directory = self.make_path('xyzzy') file_contents = 'Spam eggs' file_path = self.os.path.join(directory, 'eggs') self.create_file(file_path, contents=file_contents) self.os.rename(file_path, file_path) self.check_contents(file_path, file_contents) def test_rmdir(self): """Can remove a directory.""" directory = self.make_path('xyzzy') sub_dir = self.make_path('xyzzy', 'abccd') other_dir = self.make_path('xyzzy', 'cdeed') self.create_dir(directory) self.assertTrue(self.os.path.exists(directory)) self.os.rmdir(directory) self.assertFalse(self.os.path.exists(directory)) self.create_dir(sub_dir) self.create_dir(other_dir) self.os.chdir(sub_dir) self.os.rmdir('../cdeed') self.assertFalse(self.os.path.exists(other_dir)) self.os.chdir('..') self.os.rmdir('abccd') self.assertFalse(self.os.path.exists(sub_dir)) def test_rmdir_raises_if_not_empty(self): """Raises an exception if the target directory is not empty.""" directory = self.make_path('xyzzy') file_path = self.os.path.join(directory, 'plugh') self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.assert_raises_os_error(errno.ENOTEMPTY, self.os.rmdir, directory) def check_rmdir_raises_if_not_directory(self, error_nr): """Raises an exception if the target is not a directory.""" directory = self.make_path('xyzzy') file_path = self.os.path.join(directory, 'plugh') self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.assert_raises_os_error(self.not_dir_error(), self.os.rmdir, file_path) self.assert_raises_os_error(error_nr, self.os.rmdir, '.') def test_rmdir_raises_if_not_directory_posix(self): self.check_posix_only() self.check_rmdir_raises_if_not_directory(errno.EINVAL) def test_rmdir_raises_if_not_directory_windows(self): self.check_windows_only() self.check_rmdir_raises_if_not_directory(errno.EACCES) def test_rmdir_raises_if_not_exist(self): """Raises an exception if the target does not exist.""" directory = self.make_path('xyzzy') self.assertFalse(self.os.path.exists(directory)) self.assert_raises_os_error(errno.ENOENT, self.os.rmdir, directory) def test_rmdir_via_symlink(self): self.check_windows_only() self.skip_if_symlink_not_supported() base_path = self.make_path('foo', 'bar') dir_path = self.os.path.join(base_path, 'alpha') self.create_dir(dir_path) link_path = self.os.path.join(base_path, 'beta') self.os.symlink(base_path, link_path) self.os.rmdir(link_path + '/alpha') self.assertFalse(self.os.path.exists(dir_path)) def remove_dirs_check(self, directory): self.assertTrue(self.os.path.exists(directory)) self.os.removedirs(directory) return not self.os.path.exists(directory) def test_removedirs(self): # no exception raised self.skip_real_fs() data = ['test1', ('test1', 'test2'), ('test1', 'extra'), ('test1', 'test2', 'test3')] for directory in data: self.create_dir(self.make_path(directory)) self.assertTrue(self.os.path.exists(self.make_path(directory))) self.assert_raises_os_error(errno.ENOTEMPTY, self.remove_dirs_check, self.make_path(data[0])) self.assert_raises_os_error(errno.ENOTEMPTY, self.remove_dirs_check, self.make_path(data[1])) self.assertTrue(self.remove_dirs_check(self.make_path(data[3]))) self.assertTrue(self.os.path.exists(self.make_path(data[0]))) self.assertFalse(self.os.path.exists(self.make_path(data[1]))) self.assertTrue(self.os.path.exists(self.make_path(data[2]))) # Should raise because '/test1/extra' is all that is left, and # removedirs('/test1/extra') will eventually try to rmdir('/'). self.assert_raises_os_error(errno.EBUSY, self.remove_dirs_check, self.make_path(data[2])) # However, it will still delete '/test1') in the process. self.assertFalse(self.os.path.exists(self.make_path(data[0]))) self.create_dir(self.make_path('test1', 'test2')) # Add this to the root directory to avoid raising an exception. self.filesystem.create_dir(self.make_path('test3')) self.assertTrue( self.remove_dirs_check(self.make_path('test1', 'test2'))) self.assertFalse(self.os.path.exists(self.make_path('test1', 'test2'))) self.assertFalse(self.os.path.exists(self.make_path('test1'))) def test_removedirs_raises_if_removing_root(self): """Raises exception if asked to remove '/'.""" self.skip_real_fs() self.os.rmdir(self.base_path) directory = self.os.path.splitdrive( self.base_path)[0] + self.os.path.sep self.assertTrue(self.os.path.exists(directory)) self.assert_raises_os_error(errno.EBUSY, self.os.removedirs, directory) def test_removedirs_raises_if_cascade_removing_root(self): """Raises exception if asked to remove '/' as part of a larger operation. All of other directories should still be removed, though. """ self.skip_real_fs() directory = self.make_path('foo', 'bar') self.create_dir(directory) self.assertTrue(self.os.path.exists(directory)) self.assert_raises_os_error(errno.EBUSY, self.os.removedirs, directory) head, unused_tail = self.os.path.split(directory) while self.os.path.splitdrive(head)[1] != self.os.path.sep: self.assertFalse(self.os.path.exists(directory)) head, unused_tail = self.os.path.split(head) def test_removedirs_with_trailing_slash(self): """removedirs works on directory names with trailing slashes.""" # separate this case from the removing-root-directory case self.create_dir(self.make_path('baz')) directory = self.make_path('foo', 'bar') self.create_dir(directory) self.assertTrue(self.os.path.exists(directory)) self.os.removedirs(directory) self.assertFalse(self.os.path.exists(directory)) def test_remove_dirs_with_top_symlink_fails(self): self.check_posix_only() dir_path = self.make_path('dir') dir_link = self.make_path('dir_link') self.create_dir(dir_path) self.os.symlink(dir_path, dir_link) self.assert_raises_os_error(errno.ENOTDIR, self.os.removedirs, dir_link) def test_remove_dirs_with_non_top_symlink_succeeds(self): self.check_posix_only() dir_path = self.make_path('dir') dir_link = self.make_path('dir_link') self.create_dir(dir_path) self.os.symlink(dir_path, dir_link) dir_in_dir = self.os.path.join(dir_link, 'dir2') self.create_dir(dir_in_dir) self.os.removedirs(dir_in_dir) self.assertFalse(self.os.path.exists(dir_in_dir)) # ensure that the symlink is not removed self.assertTrue(self.os.path.exists(dir_link)) def test_mkdir(self): """mkdir can create a relative directory.""" self.skip_real_fs() directory = 'xyzzy' self.assertFalse(self.filesystem.exists(directory)) self.os.mkdir(directory) self.assertTrue(self.filesystem.exists('/%s' % directory)) self.os.chdir(directory) self.os.mkdir(directory) self.assertTrue( self.filesystem.exists('/%s/%s' % (directory, directory))) self.os.chdir(directory) self.os.mkdir('../abccb') self.assertTrue(self.os.path.exists('/%s/abccb' % directory)) def test_mkdir_with_trailing_slash(self): """mkdir can create a directory named with a trailing slash.""" directory = self.make_path('foo') self.assertFalse(self.os.path.exists(directory)) self.os.mkdir(directory) self.assertTrue(self.os.path.exists(directory)) self.assertTrue(self.os.path.exists(self.make_path('foo'))) def test_mkdir_raises_if_empty_directory_name(self): """mkdir raises exeption if creating directory named ''.""" directory = '' self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) def test_mkdir_raises_if_no_parent(self): """mkdir raises exception if parent directory does not exist.""" parent = 'xyzzy' directory = '%s/foo' % (parent,) self.assertFalse(self.os.path.exists(parent)) self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) def test_mkdir_raises_on_symlink_in_posix(self): self.check_posix_only() base_path = self.make_path('foo', 'bar') link_path = self.os.path.join(base_path, 'link_to_dir') dir_path = self.os.path.join(base_path, 'dir') self.create_dir(dir_path) self.os.symlink(dir_path, link_path) self.assert_raises_os_error(errno.ENOTDIR, self.os.rmdir, link_path) def test_mkdir_removes_symlink_in_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() base_path = self.make_path('foo', 'bar') link_path = self.os.path.join(base_path, 'link_to_dir') dir_path = self.os.path.join(base_path, 'dir') self.create_dir(dir_path) self.os.symlink(dir_path, link_path) self.os.rmdir(link_path) self.assertFalse(self.os.path.exists(link_path)) self.assertTrue(self.os.path.exists(dir_path)) def test_mkdir_raises_if_directory_exists(self): """mkdir raises exception if directory already exists.""" directory = self.make_path('xyzzy') self.create_dir(directory) self.assertTrue(self.os.path.exists(directory)) self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, directory) def test_mkdir_raises_if_file_exists(self): """mkdir raises exception if name already exists as a file.""" directory = self.make_path('xyzzy') file_path = self.os.path.join(directory, 'plugh') self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, file_path) def check_mkdir_raises_if_parent_is_file(self, error_type): """mkdir raises exception if name already exists as a file.""" directory = self.make_path('xyzzy') file_path = self.os.path.join(directory, 'plugh') self.create_file(file_path) self.assert_raises_os_error(error_type, self.os.mkdir, self.os.path.join(file_path, 'ff')) def test_mkdir_raises_if_parent_is_file_posix(self): self.check_posix_only() self.check_mkdir_raises_if_parent_is_file(errno.ENOTDIR) def test_mkdir_raises_if_parent_is_file_windows(self): self.check_windows_only() self.check_mkdir_raises_if_parent_is_file(errno.ENOENT) def test_mkdir_raises_with_slash_dot_posix(self): """mkdir raises exception if mkdir foo/. (trailing /.).""" self.check_posix_only() self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, self.os.sep + '.') directory = self.make_path('xyzzy', '.') self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) self.create_dir(self.make_path('xyzzy')) self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, directory) def test_mkdir_raises_with_slash_dot_windows(self): """mkdir raises exception if mkdir foo/. (trailing /.).""" self.check_windows_only() self.assert_raises_os_error(errno.EACCES, self.os.mkdir, self.os.sep + '.') directory = self.make_path('xyzzy', '.') self.os.mkdir(directory) self.create_dir(self.make_path('xyzzy')) self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, directory) def test_mkdir_raises_with_double_dots_posix(self): """mkdir raises exception if mkdir foo/foo2/../foo3.""" self.check_posix_only() self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, self.os.sep + '..') directory = self.make_path('xyzzy', 'dir1', 'dir2', '..', '..', 'dir3') self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) self.create_dir(self.make_path('xyzzy')) self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) self.create_dir(self.make_path('xyzzy', 'dir1')) self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) self.create_dir(self.make_path('xyzzy', 'dir1', 'dir2')) self.os.mkdir(directory) self.assertTrue(self.os.path.exists(directory)) directory = self.make_path('xyzzy', 'dir1', '..') self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, directory) def test_mkdir_raises_with_double_dots_windows(self): """mkdir raises exception if mkdir foo/foo2/../foo3.""" self.check_windows_only() self.assert_raises_os_error(errno.EACCES, self.os.mkdir, self.os.sep + '..') directory = self.make_path( 'xyzzy', 'dir1', 'dir2', '..', '..', 'dir3') self.assert_raises_os_error(errno.ENOENT, self.os.mkdir, directory) self.create_dir(self.make_path('xyzzy')) self.os.mkdir(directory) self.assertTrue(self.os.path.exists(directory)) directory = self.make_path('xyzzy', 'dir1', '..') self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, directory) def test_mkdir_raises_if_parent_is_read_only(self): """mkdir raises exception if parent is read only.""" self.check_posix_only() directory = self.make_path('a') self.os.mkdir(directory) # Change directory permissions to be read only. self.os.chmod(directory, 0o400) directory = self.make_path('a', 'b') if not is_root(): self.assert_raises_os_error(errno.EACCES, self.os.mkdir, directory) else: self.os.mkdir(directory) self.assertTrue(self.os.path.exists(directory)) def test_mkdir_with_with_symlink_parent(self): self.check_posix_only() dir_path = self.make_path('foo', 'bar') self.create_dir(dir_path) link_path = self.make_path('foo', 'link') self.os.symlink(dir_path, link_path) new_dir = self.os.path.join(link_path, 'new_dir') self.os.mkdir(new_dir) self.assertTrue(self.os.path.exists(new_dir)) def test_makedirs(self): """makedirs can create a directory even if parent does not exist.""" parent = self.make_path('xyzzy') directory = self.os.path.join(parent, 'foo') self.assertFalse(self.os.path.exists(parent)) self.os.makedirs(directory) self.assertTrue(self.os.path.exists(directory)) def check_makedirs_raises_if_parent_is_file(self, error_type): """makedirs raises exception if a parent component exists as a file.""" file_path = self.make_path('xyzzy') directory = self.os.path.join(file_path, 'plugh') self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.assert_raises_os_error(error_type, self.os.makedirs, directory) def test_makedirs_raises_if_parent_is_file_posix(self): self.check_posix_only() self.check_makedirs_raises_if_parent_is_file(errno.ENOTDIR) def test_makedirs_raises_if_parent_is_file_windows(self): self.check_windows_only() self.check_makedirs_raises_if_parent_is_file(errno.ENOENT) def test_makedirs_raises_if_parent_is_broken_link(self): self.check_posix_only() link_path = self.make_path('broken_link') self.os.symlink(self.make_path('bogus'), link_path) self.assert_raises_os_error(errno.ENOENT, self.os.makedirs, self.os.path.join(link_path, 'newdir')) def test_makedirs_raises_if_parent_is_looping_link(self): self.skip_if_symlink_not_supported() link_path = self.make_path('link') link_target = self.os.path.join(link_path, 'link') self.os.symlink(link_target, link_path) self.assert_raises_os_error(errno.EEXIST, self.os.makedirs, link_path) def test_makedirs_if_parent_is_symlink(self): self.check_posix_only() base_dir = self.make_path('foo', 'bar') self.create_dir(base_dir) link_dir = self.os.path.join(base_dir, 'linked') self.os.symlink(base_dir, link_dir) new_dir = self.os.path.join(link_dir, 'f') self.os.makedirs(new_dir) self.assertTrue(self.os.path.exists(new_dir)) def test_makedirs_raises_if_access_denied(self): """makedirs raises exception if access denied.""" self.check_posix_only() directory = self.make_path('a') self.os.mkdir(directory) # Change directory permissions to be read only. self.os.chmod(directory, 0o400) directory = self.make_path('a', 'b') if not is_root(): self.assertRaises(Exception, self.os.makedirs, directory) else: self.os.makedirs(directory) self.assertTrue(self.os.path.exists(directory)) @unittest.skipIf(sys.version_info < (3, 2), 'os.makedirs(exist_ok) argument new in version 3.2') def test_makedirs_exist_ok(self): """makedirs uses the exist_ok argument""" directory = self.make_path('xyzzy', 'foo') self.create_dir(directory) self.assertTrue(self.os.path.exists(directory)) self.assert_raises_os_error(errno.EEXIST, self.os.makedirs, directory) self.os.makedirs(directory, exist_ok=True) self.assertTrue(self.os.path.exists(directory)) # test fsync and fdatasync def test_fsync_raises_on_non_int(self): self.assertRaises(TypeError, self.os.fsync, "zero") def test_fdatasync_raises_on_non_int(self): self.check_linux_only() self.assertRaises(TypeError, self.os.fdatasync, "zero") def test_fsync_raises_on_invalid_fd(self): self.assert_raises_os_error(errno.EBADF, self.os.fsync, 100) def test_fdatasync_raises_on_invalid_fd(self): # No open files yet self.check_linux_only() self.assert_raises_os_error(errno.EINVAL, self.os.fdatasync, 0) self.assert_raises_os_error(errno.EBADF, self.os.fdatasync, 100) def test_fsync_pass_posix(self): self.check_posix_only() test_file_path = self.make_path('test_file') self.create_file(test_file_path, contents='dummy file contents') with self.open(test_file_path, 'r') as test_file: test_fd = test_file.fileno() # Test that this doesn't raise anything self.os.fsync(test_fd) # And just for sanity, double-check that this still raises self.assert_raises_os_error(errno.EBADF, self.os.fsync, test_fd + 10) def test_fsync_pass_windows(self): self.check_windows_only() test_file_path = self.make_path('test_file') self.create_file(test_file_path, contents='dummy file contents') with self.open(test_file_path, 'r+') as test_file: test_fd = test_file.fileno() # Test that this doesn't raise anything self.os.fsync(test_fd) # And just for sanity, double-check that this still raises self.assert_raises_os_error(errno.EBADF, self.os.fsync, test_fd + 10) with self.open(test_file_path, 'r') as test_file: test_fd = test_file.fileno() self.assert_raises_os_error(errno.EBADF, self.os.fsync, test_fd) def test_fdatasync_pass(self): # setup self.check_linux_only() test_file_path = self.make_path('test_file') self.create_file(test_file_path, contents='dummy file contents') test_file = self.open(test_file_path, 'r') test_fd = test_file.fileno() # Test that this doesn't raise anything self.os.fdatasync(test_fd) # And just for sanity, double-check that this still raises self.assert_raises_os_error(errno.EBADF, self.os.fdatasync, test_fd + 10) def test_access700(self): # set up self.check_posix_only() path = self.make_path('some_file') self.createTestFile(path) self.os.chmod(path, 0o700) self.assert_mode_equal(0o700, self.os.stat(path).st_mode) # actual tests self.assertTrue(self.os.access(path, self.os.F_OK)) self.assertTrue(self.os.access(path, self.os.R_OK)) self.assertTrue(self.os.access(path, self.os.W_OK)) self.assertTrue(self.os.access(path, self.os.X_OK)) self.assertTrue(self.os.access(path, self.rwx)) def test_access600(self): # set up self.check_posix_only() path = self.make_path('some_file') self.createTestFile(path) self.os.chmod(path, 0o600) self.assert_mode_equal(0o600, self.os.stat(path).st_mode) # actual tests self.assertTrue(self.os.access(path, self.os.F_OK)) self.assertTrue(self.os.access(path, self.os.R_OK)) self.assertTrue(self.os.access(path, self.os.W_OK)) self.assertFalse(self.os.access(path, self.os.X_OK)) self.assertFalse(self.os.access(path, self.rwx)) self.assertTrue(self.os.access(path, self.rw)) def test_access400(self): # set up self.check_posix_only() path = self.make_path('some_file') self.createTestFile(path) self.os.chmod(path, 0o400) self.assert_mode_equal(0o400, self.os.stat(path).st_mode) # actual tests self.assertTrue(self.os.access(path, self.os.F_OK)) self.assertTrue(self.os.access(path, self.os.R_OK)) self.assertFalse(self.os.access(path, self.os.X_OK)) self.assertFalse(self.os.access(path, self.rwx)) if is_root(): self.assertTrue(self.os.access(path, self.os.W_OK)) self.assertTrue(self.os.access(path, self.rw)) else: self.assertFalse(self.os.access(path, self.os.W_OK)) self.assertFalse(self.os.access(path, self.rw)) @unittest.skipIf(sys.version_info < (3, 3), 'follow_symlinks new in Python 3.3') def test_access_symlink(self): self.skip_if_symlink_not_supported() self.skip_real_fs() path = self.make_path('some_file') self.createTestFile(path) link_path = self.make_path('link_to_some_file') self.create_symlink(link_path, path) self.os.chmod(link_path, 0o400) # test file self.assertTrue(self.os.access(link_path, self.os.F_OK)) self.assertTrue(self.os.access(link_path, self.os.R_OK)) if is_root(): self.assertTrue(self.os.access(link_path, self.os.W_OK)) self.assertTrue(self.os.access(link_path, self.rw)) else: self.assertFalse(self.os.access(link_path, self.os.W_OK)) self.assertFalse(self.os.access(link_path, self.rw)) self.assertFalse(self.os.access(link_path, self.os.X_OK)) self.assertFalse(self.os.access(link_path, self.rwx)) # test link itself self.assertTrue( self.os.access(link_path, self.os.F_OK, follow_symlinks=False)) self.assertTrue( self.os.access(link_path, self.os.R_OK, follow_symlinks=False)) self.assertTrue( self.os.access(link_path, self.os.W_OK, follow_symlinks=False)) self.assertTrue( self.os.access(link_path, self.os.X_OK, follow_symlinks=False)) self.assertTrue( self.os.access(link_path, self.rwx, follow_symlinks=False)) self.assertTrue( self.os.access(link_path, self.rw, follow_symlinks=False)) def test_access_non_existent_file(self): # set up path = self.make_path('non', 'existent', 'file') self.assertFalse(self.os.path.exists(path)) # actual tests self.assertFalse(self.os.access(path, self.os.F_OK)) self.assertFalse(self.os.access(path, self.os.R_OK)) self.assertFalse(self.os.access(path, self.os.W_OK)) self.assertFalse(self.os.access(path, self.os.X_OK)) self.assertFalse(self.os.access(path, self.rwx)) self.assertFalse(self.os.access(path, self.rw)) def test_chmod(self): # set up self.check_posix_only() self.skip_real_fs() path = self.make_path('some_file') self.createTestFile(path) # actual tests self.os.chmod(path, 0o6543) st = self.os.stat(path) self.assert_mode_equal(0o6543, st.st_mode) self.assertTrue(st.st_mode & stat.S_IFREG) self.assertFalse(st.st_mode & stat.S_IFDIR) @unittest.skipIf(sys.version_info < (3, 3), 'file descriptor as path new in Python 3.3') def test_chmod_uses_open_fd_as_path(self): self.check_posix_only() self.skip_real_fs() self.assert_raises_os_error(errno.EBADF, self.os.chmod, 5, 0o6543) path = self.make_path('some_file') self.createTestFile(path) with self.open(path) as f: self.os.chmod(f.filedes, 0o6543) st = self.os.stat(path) self.assert_mode_equal(0o6543, st.st_mode) @unittest.skipIf(sys.version_info < (3, 3), 'follow_symlinks new in Python 3.3') def test_chmod_follow_symlink(self): self.check_posix_only() if self.use_real_fs() and 'chmod' not in os.supports_follow_symlinks: raise unittest.SkipTest('follow_symlinks not available') path = self.make_path('some_file') self.createTestFile(path) link_path = self.make_path('link_to_some_file') self.create_symlink(link_path, path) self.os.chmod(link_path, 0o6543) st = self.os.stat(link_path) self.assert_mode_equal(0o6543, st.st_mode) st = self.os.stat(link_path, follow_symlinks=False) self.assert_mode_equal(0o777, st.st_mode) @unittest.skipIf(sys.version_info < (3, 3), 'follow_symlinks new in Python 3.3') def test_chmod_no_follow_symlink(self): self.check_posix_only() if self.use_real_fs() and 'chmod' not in os.supports_follow_symlinks: raise unittest.SkipTest('follow_symlinks not available') path = self.make_path('some_file') self.createTestFile(path) link_path = self.make_path('link_to_some_file') self.create_symlink(link_path, path) self.os.chmod(link_path, 0o6543, follow_symlinks=False) st = self.os.stat(link_path) self.assert_mode_equal(0o666, st.st_mode) st = self.os.stat(link_path, follow_symlinks=False) self.assert_mode_equal(0o6543, st.st_mode) def test_lchmod(self): """lchmod shall behave like chmod with follow_symlinks=True since Python 3.3""" self.check_posix_only() self.skip_real_fs() path = self.make_path('some_file') self.createTestFile(path) link_path = self.make_path('link_to_some_file') self.create_symlink(link_path, path) self.os.lchmod(link_path, 0o6543) st = self.os.stat(link_path) self.assert_mode_equal(0o666, st.st_mode) st = self.os.lstat(link_path) self.assert_mode_equal(0o6543, st.st_mode) def test_chmod_dir(self): # set up self.check_posix_only() self.skip_real_fs() path = self.make_path('some_dir') self.createTestDirectory(path) # actual tests self.os.chmod(path, 0o1234) st = self.os.stat(path) self.assert_mode_equal(0o1234, st.st_mode) self.assertFalse(st.st_mode & stat.S_IFREG) self.assertTrue(st.st_mode & stat.S_IFDIR) def test_chmod_non_existent(self): # set up path = self.make_path('non', 'existent', 'file') self.assertFalse(self.os.path.exists(path)) # actual tests try: # Use try-catch to check exception attributes. self.os.chmod(path, 0o777) self.fail('Exception is expected.') # COV_NF_LINE except OSError as os_error: self.assertEqual(errno.ENOENT, os_error.errno) self.assertEqual(path, os_error.filename) def test_chown_existing_file(self): # set up self.skip_real_fs() file_path = self.make_path('some_file') self.create_file(file_path) # first set it make sure it's set self.os.chown(file_path, 100, 101) st = self.os.stat(file_path) self.assertEqual(st[stat.ST_UID], 100) self.assertEqual(st[stat.ST_GID], 101) # we can make sure it changed self.os.chown(file_path, 200, 201) st = self.os.stat(file_path) self.assertEqual(st[stat.ST_UID], 200) self.assertEqual(st[stat.ST_GID], 201) # setting a value to -1 leaves it unchanged self.os.chown(file_path, -1, -1) st = self.os.stat(file_path) self.assertEqual(st[stat.ST_UID], 200) self.assertEqual(st[stat.ST_GID], 201) @unittest.skipIf(sys.version_info < (3, 3), 'file descriptor as path new in Python 3.3') def test_chown_uses_open_fd_as_path(self): self.check_posix_only() self.skip_real_fs() self.assert_raises_os_error(errno.EBADF, self.os.chown, 5, 100, 101) file_path = self.make_path('foo', 'bar') self.create_file(file_path) with self.open(file_path) as f: self.os.chown(f.filedes, 100, 101) st = self.os.stat(file_path) self.assertEqual(st[stat.ST_UID], 100) @unittest.skipIf(sys.version_info < (3, 3), 'follow_symlinks new in Python 3.3') def test_chown_follow_symlink(self): self.skip_real_fs() file_path = self.make_path('some_file') self.create_file(file_path) link_path = self.make_path('link_to_some_file') self.create_symlink(link_path, file_path) self.os.chown(link_path, 100, 101) st = self.os.stat(link_path) self.assertEqual(st[stat.ST_UID], 100) self.assertEqual(st[stat.ST_GID], 101) st = self.os.stat(link_path, follow_symlinks=False) self.assertNotEqual(st[stat.ST_UID], 100) self.assertNotEqual(st[stat.ST_GID], 101) @unittest.skipIf(sys.version_info < (3, 3), 'follow_symlinks new in Python 3.3') def test_chown_no_follow_symlink(self): self.skip_real_fs() file_path = self.make_path('some_file') self.create_file(file_path) link_path = self.make_path('link_to_some_file') self.create_symlink(link_path, file_path) self.os.chown(link_path, 100, 101, follow_symlinks=False) st = self.os.stat(link_path) self.assertNotEqual(st[stat.ST_UID], 100) self.assertNotEqual(st[stat.ST_GID], 101) st = self.os.stat(link_path, follow_symlinks=False) self.assertEqual(st[stat.ST_UID], 100) self.assertEqual(st[stat.ST_GID], 101) def test_chown_bad_arguments(self): """os.chown() with bad args (Issue #30)""" self.check_posix_only() file_path = self.make_path('some_file') self.create_file(file_path) self.assertRaises(TypeError, self.os.chown, file_path, 'username', -1) self.assertRaises(TypeError, self.os.chown, file_path, -1, 'groupname') def test_chown_nonexisting_file_should_raise_os_error(self): self.check_posix_only() file_path = self.make_path('some_file') self.assertFalse(self.os.path.exists(file_path)) self.assert_raises_os_error( errno.ENOENT, self.os.chown, file_path, 100, 100) def test_classify_directory_contents(self): """Directory classification should work correctly.""" root_directory = self.make_path('foo') test_directories = ['bar1', 'baz2'] test_files = ['baz1', 'bar2', 'baz3'] self.create_dir(root_directory) for directory in test_directories: directory = self.os.path.join(root_directory, directory) self.create_dir(directory) for test_file in test_files: test_file = self.os.path.join(root_directory, test_file) self.create_file(test_file) test_directories.sort() test_files.sort() generator = self.os.walk(root_directory) root, dirs, files = next(generator) dirs.sort() files.sort() self.assertEqual(root_directory, root) self.assertEqual(test_directories, dirs) self.assertEqual(test_files, files) # os.mknod does not work under MacOS due to permission issues # so we test it under Linux only def test_mk_nod_can_create_a_file(self): self.check_linux_only() filename = self.make_path('foo') self.assertFalse(self.os.path.exists(filename)) self.os.mknod(filename) self.assertTrue(self.os.path.exists(filename)) self.assertEqual(stat.S_IFREG | 0o600, self.os.stat(filename).st_mode) def test_mk_nod_raises_if_empty_file_name(self): self.check_linux_only() filename = '' self.assert_raises_os_error(errno.ENOENT, self.os.mknod, filename) def test_mk_nod_raises_if_parent_dir_doesnt_exist(self): self.check_linux_only() parent = self.make_path('xyzzy') filename = self.os.path.join(parent, 'foo') self.assertFalse(self.os.path.exists(parent)) self.assert_raises_os_error(errno.ENOENT, self.os.mknod, filename) def test_mk_nod_raises_if_file_exists(self): self.check_linux_only() filename = self.make_path('tmp', 'foo') self.create_file(filename) self.assertTrue(self.os.path.exists(filename)) self.assert_raises_os_error(errno.EEXIST, self.os.mknod, filename) def test_mk_nod_raises_if_filename_is_dot(self): self.check_linux_only() filename = self.make_path('tmp', '.') self.assert_raises_os_error(errno.ENOENT, self.os.mknod, filename) def test_mk_nod_raises_if_filename_is_double_dot(self): self.check_linux_only() filename = self.make_path('tmp', '..') self.assert_raises_os_error(errno.ENOENT, self.os.mknod, filename) def test_mknod_empty_tail_for_existing_file_raises(self): self.check_linux_only() filename = self.make_path('foo') self.create_file(filename) self.assertTrue(self.os.path.exists(filename)) self.assert_raises_os_error(errno.EEXIST, self.os.mknod, filename) def test_mknod_empty_tail_for_nonexistent_file_raises(self): self.check_linux_only() filename = self.make_path('tmp', 'foo') self.assert_raises_os_error(errno.ENOENT, self.os.mknod, filename) def test_mknod_raises_if_filename_is_empty_string(self): self.check_linux_only() filename = '' self.assert_raises_os_error(errno.ENOENT, self.os.mknod, filename) def test_mknod_raises_if_unsupported_options(self): self.check_posix_only() filename = 'abcde' if not is_root(): self.assert_raises_os_error(errno.EPERM, self.os.mknod, filename, stat.S_IFCHR) else: self.os.mknod(filename, stat.S_IFCHR) self.os.remove(filename) def test_mknod_raises_if_parent_is_not_a_directory(self): self.check_linux_only() filename1 = self.make_path('foo') self.create_file(filename1) self.assertTrue(self.os.path.exists(filename1)) filename2 = self.make_path('foo', 'bar') self.assert_raises_os_error(errno.ENOTDIR, self.os.mknod, filename2) def test_symlink(self): self.skip_if_symlink_not_supported() file_path = self.make_path('foo', 'bar', 'baz') self.create_dir(self.make_path('foo', 'bar')) self.os.symlink('bogus', file_path) self.assertTrue(self.os.path.lexists(file_path)) self.assertFalse(self.os.path.exists(file_path)) self.create_file(self.make_path('foo', 'bar', 'bogus')) self.assertTrue(self.os.path.lexists(file_path)) self.assertTrue(self.os.path.exists(file_path)) def test_symlink_on_nonexisting_path_raises(self): self.check_posix_only() dir_path = self.make_path('bar') link_path = self.os.path.join(dir_path, 'bar') self.assert_raises_os_error(errno.ENOENT, self.os.symlink, link_path, link_path) self.assert_raises_os_error(errno.ENOENT, self.os.symlink, dir_path, link_path) def test_symlink_with_path_ending_with_sep_in_posix(self): self.check_posix_only() dir_path = self.make_path('dir') self.create_dir(dir_path) self.assert_raises_os_error(errno.EEXIST, self.os.symlink, self.base_path, dir_path + self.os.sep) dir_path = self.make_path('bar') self.assert_raises_os_error(errno.ENOENT, self.os.symlink, self.base_path, dir_path + self.os.sep) def test_symlink_with_path_ending_with_sep_in_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() dir_path = self.make_path('dir') self.create_dir(dir_path) self.assert_raises_os_error(errno.EEXIST, self.os.symlink, self.base_path, dir_path + self.os.sep) dir_path = self.make_path('bar') # does not raise under Windows self.os.symlink(self.base_path, dir_path + self.os.sep) def test_broken_symlink_with_trailing_sep_posix(self): # Regression test for #390 self.check_linux_only() path0 = self.make_path('foo') + self.os.sep self.assert_raises_os_error( errno.ENOENT, self.os.symlink, path0, path0) def test_broken_symlink_with_trailing_sep_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() path0 = self.make_path('foo') + self.os.sep self.assert_raises_os_error( errno.EINVAL, self.os.symlink, path0, path0) def test_rename_symlink_with_trailing_sep_linux(self): # Regression test for #391 self.check_linux_only() path = self.make_path('foo') self.os.symlink(self.base_path, path) self.assert_raises_os_error(errno.ENOTDIR, self.os.rename, path + self.os.sep, self.base_path) def test_rename_symlink_with_trailing_sep_macos(self): # Regression test for #391 self.check_macos_only() path = self.make_path('foo') self.os.symlink(self.base_path, path) self.os.rename(path + self.os.sep, self.base_path) def test_rename_symlink_with_trailing_sep_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() path = self.make_path('foo') self.os.symlink(self.base_path, path) self.assert_raises_os_error(errno.EEXIST, self.os.rename, path + self.os.sep, self.base_path) def test_rename_symlink_to_other_case(self): # Regression test for #389 self.skip_if_symlink_not_supported() link_path = self.make_path('foo') self.os.symlink(self.base_path, link_path) link_to_link_path = self.make_path('BAR') self.os.symlink(link_path, link_to_link_path) new_link_to_link_path = self.os.path.join(link_path, 'bar') self.os.rename(link_to_link_path, new_link_to_link_path) self.assertEqual(['bar', 'foo'], sorted(self.os.listdir(new_link_to_link_path))) def create_broken_link_path_with_trailing_sep(self): # Regression tests for #396 self.skip_if_symlink_not_supported() link_path = self.make_path('link') target_path = self.make_path('target') self.os.symlink(target_path, link_path) link_path += self.os.sep return link_path def test_lstat_broken_link_with_trailing_sep_linux(self): self.check_linux_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error(errno.ENOENT, self.os.lstat, link_path) def test_lstat_broken_link_with_trailing_sep_macos(self): self.check_macos_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error(errno.ENOENT, self.os.lstat, link_path) def test_lstat_broken_link_with_trailing_sep_windows(self): self.check_windows_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error(errno.EINVAL, self.os.lstat, link_path) def test_mkdir_broken_link_with_trailing_sep_linux_windows(self): self.check_linux_and_windows() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, link_path) self.assert_raises_os_error(errno.EEXIST, self.os.makedirs, link_path) def test_mkdir_broken_link_with_trailing_sep_macos(self): self.check_macos_only() link_path = self.create_broken_link_path_with_trailing_sep() self.os.mkdir(link_path) # no error def test_makedirs_broken_link_with_trailing_sep_macos(self): self.check_macos_only() link_path = self.create_broken_link_path_with_trailing_sep() self.os.makedirs(link_path) # no error def test_remove_broken_link_with_trailing_sep_linux(self): self.check_linux_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error(errno.ENOTDIR, self.os.remove, link_path) def test_remove_broken_link_with_trailing_sep_macos(self): self.check_macos_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error(errno.ENOENT, self.os.remove, link_path) def test_remove_broken_link_with_trailing_sep_windows(self): self.check_windows_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error(errno.EINVAL, self.os.remove, link_path) def test_rename_broken_link_with_trailing_sep_linux(self): self.check_linux_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error( errno.ENOTDIR, self.os.rename, link_path, self.make_path('target')) def test_rename_broken_link_with_trailing_sep_macos(self): self.check_macos_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error( errno.ENOENT, self.os.rename, link_path, self.make_path('target')) def test_rename_broken_link_with_trailing_sep_windows(self): self.check_windows_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error( errno.EINVAL, self.os.rename, link_path, self.make_path('target')) def test_readlink_broken_link_with_trailing_sep_posix(self): self.check_posix_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error(errno.ENOENT, self.os.readlink, link_path) def test_readlink_broken_link_with_trailing_sep_windows(self): self.check_windows_only() link_path = self.create_broken_link_path_with_trailing_sep() self.assert_raises_os_error(errno.EINVAL, self.os.readlink, link_path) def test_islink_broken_link_with_trailing_sep(self): link_path = self.create_broken_link_path_with_trailing_sep() self.assertFalse(self.os.path.islink(link_path)) def test_lexists_broken_link_with_trailing_sep(self): link_path = self.create_broken_link_path_with_trailing_sep() self.assertFalse(self.os.path.lexists(link_path)) def test_rename_link_with_trailing_sep_to_self_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() path = self.make_path('foo') self.os.symlink(self.base_path, path) self.os.rename(path + self.os.sep, path) # no error def test_rename_link_with_trailing_sep_to_self_posix(self): # Regression test for #395 self.check_posix_only() path = self.make_path('foo') self.os.symlink(self.base_path, path) self.assert_raises_os_error( errno.ENOTDIR, self.os.rename, path + self.os.sep, path) def check_open_broken_symlink_to_path_with_trailing_sep(self, error): # Regression tests for #397 self.skip_if_symlink_not_supported() target_path = self.make_path('target') + self.os.sep link_path = self.make_path('link') self.os.symlink(target_path, link_path) self.assert_raises_io_error(error, self.open, link_path, 'a') self.assert_raises_io_error(error, self.open, link_path, 'w') def test_open_broken_symlink_to_path_with_trailing_sep_linux(self): self.check_linux_only() self.check_open_broken_symlink_to_path_with_trailing_sep(errno.EISDIR) def test_open_broken_symlink_to_path_with_trailing_sep_macos(self): self.check_macos_only() self.check_open_broken_symlink_to_path_with_trailing_sep(errno.ENOENT) def test_open_broken_symlink_to_path_with_trailing_sep_windows(self): self.check_windows_only() self.check_open_broken_symlink_to_path_with_trailing_sep(errno.EINVAL) def check_link_path_ending_with_sep(self, error): # Regression tests for #399 self.skip_if_symlink_not_supported() file_path = self.make_path('foo') link_path = self.make_path('link') with self.open(file_path, 'w'): self.assert_raises_os_error( error, self.os.link, file_path + self.os.sep, link_path) def test_link_path_ending_with_sep_posix(self): self.check_posix_only() self.check_link_path_ending_with_sep(errno.ENOTDIR) def test_link_path_ending_with_sep_windows(self): self.check_windows_only() self.check_link_path_ending_with_sep(errno.EINVAL) def test_link_to_path_ending_with_sep_posix(self): # regression test for #407 self.check_posix_only() path0 = self.make_path('foo') + self.os.sep path1 = self.make_path('bar') with self.open(path1, 'w'): self.assert_raises_os_error(errno.ENOENT, self.os.link, path1, path0) def test_link_to_path_ending_with_sep_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() path0 = self.make_path('foo') + self.os.sep path1 = self.make_path('bar') with self.open(path1, 'w'): self.os.link(path1, path0) self.assertTrue(self.os.path.exists(path1)) def check_rename_to_path_ending_with_sep(self, error): # Regression tests for #400 file_path = self.make_path('foo') with self.open(file_path, 'w'): self.assert_raises_os_error( error, self.os.rename, file_path + self.os.sep, file_path) def test_rename_to_path_ending_with_sep_posix(self): self.check_posix_only() self.check_rename_to_path_ending_with_sep(errno.ENOTDIR) def test_rename_to_path_ending_with_sep_windows(self): self.check_windows_only() self.check_rename_to_path_ending_with_sep(errno.EINVAL) def test_rmdir_link_with_trailing_sep_linux(self): self.check_linux_only() dir_path = self.make_path('foo') self.os.mkdir(dir_path) link_path = self.make_path('link') self.os.symlink(dir_path, link_path) self.assert_raises_os_error( errno.ENOTDIR, self.os.rmdir, link_path + self.os.sep) def test_rmdir_link_with_trailing_sep_macos(self): # Regression test for #398 self.check_macos_only() dir_path = self.make_path('foo') self.os.mkdir(dir_path) link_path = self.make_path('link') self.os.symlink(dir_path, link_path) self.os.rmdir(link_path + self.os.sep) self.assertFalse(self.os.path.exists(link_path)) def test_rmdir_link_with_trailing_sep_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() dir_path = self.make_path('foo') self.os.mkdir(dir_path) link_path = self.make_path('link') self.os.symlink(dir_path, link_path) self.os.rmdir(link_path + self.os.sep) self.assertFalse(self.os.path.exists(link_path)) def test_readlink_circular_link_with_trailing_sep_linux(self): self.check_linux_only() path1 = self.make_path('foo') path0 = self.make_path('bar') self.os.symlink(path0, path1) self.os.symlink(path1, path0) self.assert_raises_os_error( errno.ELOOP, self.os.readlink, path0 + self.os.sep) def test_readlink_circular_link_with_trailing_sep_macos(self): # Regression test for #392 self.check_macos_only() path1 = self.make_path('foo') path0 = self.make_path('bar') self.os.symlink(path0, path1) self.os.symlink(path1, path0) self.assertEqual(path0, self.os.readlink(path0 + self.os.sep)) def test_readlink_circular_link_with_trailing_sep_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() path1 = self.make_path('foo') path0 = self.make_path('bar') self.os.symlink(path0, path1) self.os.symlink(path1, path0) self.assert_raises_os_error( errno.EINVAL, self.os.readlink, path0 + self.os.sep) # hard link related tests def test_link_bogus(self): # trying to create a link from a non-existent file should fail self.skip_if_symlink_not_supported() self.assert_raises_os_error(errno.ENOENT, self.os.link, '/nonexistent_source', '/link_dest') def test_link_delete(self): self.skip_if_symlink_not_supported() file1_path = self.make_path('test_file1') file2_path = self.make_path('test_file2') contents1 = 'abcdef' # Create file self.create_file(file1_path, contents=contents1) # link to second file self.os.link(file1_path, file2_path) # delete first file self.os.unlink(file1_path) # assert that second file exists, and its contents are the same self.assertTrue(self.os.path.exists(file2_path)) with self.open(file2_path) as f: self.assertEqual(f.read(), contents1) def test_link_update(self): self.skip_if_symlink_not_supported() file1_path = self.make_path('test_file1') file2_path = self.make_path('test_file2') contents1 = 'abcdef' contents2 = 'ghijkl' # Create file and link self.create_file(file1_path, contents=contents1) self.os.link(file1_path, file2_path) # assert that the second file contains contents1 with self.open(file2_path) as f: self.assertEqual(f.read(), contents1) # update the first file with self.open(file1_path, 'w') as f: f.write(contents2) # assert that second file contains contents2 with self.open(file2_path) as f: self.assertEqual(f.read(), contents2) def test_link_non_existent_parent(self): self.skip_if_symlink_not_supported() file1_path = self.make_path('test_file1') breaking_link_path = self.make_path('nonexistent', 'test_file2') contents1 = 'abcdef' # Create file and link self.create_file(file1_path, contents=contents1) # trying to create a link under a non-existent directory should fail self.assert_raises_os_error( errno.ENOENT, self.os.link, file1_path, breaking_link_path) def test_link_is_existing_file(self): self.skip_if_symlink_not_supported() file_path = self.make_path('foo', 'bar') self.create_file(file_path) self.assert_raises_os_error(errno.EEXIST, self.os.link, file_path, file_path) def test_link_target_is_dir_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() dir_path = self.make_path('foo', 'bar') link_path = self.os.path.join(dir_path, 'link') self.create_dir(dir_path) self.assert_raises_os_error(errno.EACCES, self.os.link, dir_path, link_path) def test_link_target_is_dir_posix(self): self.check_posix_only() dir_path = self.make_path('foo', 'bar') link_path = self.os.path.join(dir_path, 'link') self.create_dir(dir_path) self.assert_raises_os_error(errno.EPERM, self.os.link, dir_path, link_path) def test_link_count1(self): """Test that hard link counts are updated correctly.""" self.skip_if_symlink_not_supported() file1_path = self.make_path('test_file1') file2_path = self.make_path('test_file2') file3_path = self.make_path('test_file3') self.create_file(file1_path) # initial link count should be one self.assertEqual(self.os.stat(file1_path).st_nlink, 1) self.os.link(file1_path, file2_path) # the count should be incremented for each hard link created self.assertEqual(self.os.stat(file1_path).st_nlink, 2) self.assertEqual(self.os.stat(file2_path).st_nlink, 2) # Check that the counts are all updated together self.os.link(file2_path, file3_path) self.assertEqual(self.os.stat(file1_path).st_nlink, 3) self.assertEqual(self.os.stat(file2_path).st_nlink, 3) self.assertEqual(self.os.stat(file3_path).st_nlink, 3) # Counts should be decremented when links are removed self.os.unlink(file3_path) self.assertEqual(self.os.stat(file1_path).st_nlink, 2) self.assertEqual(self.os.stat(file2_path).st_nlink, 2) # check that it gets decremented correctly again self.os.unlink(file1_path) self.assertEqual(self.os.stat(file2_path).st_nlink, 1) def test_nlink_for_directories(self): self.skip_real_fs() self.create_dir(self.make_path('foo', 'bar')) self.create_file(self.make_path('foo', 'baz')) self.assertEqual(2, self.filesystem.get_object( self.make_path('foo', 'bar')).st_nlink) self.assertEqual(4, self.filesystem.get_object( self.make_path('foo')).st_nlink) self.create_file(self.make_path('foo', 'baz2')) self.assertEqual(5, self.filesystem.get_object( self.make_path('foo')).st_nlink) def test_umask(self): self.check_posix_only() umask = os.umask(0o22) os.umask(umask) self.assertEqual(umask, self.os.umask(0o22)) def test_mkdir_umask_applied(self): """mkdir creates a directory with umask applied.""" self.check_posix_only() self.os.umask(0o22) dir1 = self.make_path('dir1') self.os.mkdir(dir1) self.assert_mode_equal(0o755, self.os.stat(dir1).st_mode) self.os.umask(0o67) dir2 = self.make_path('dir2') self.os.mkdir(dir2) self.assert_mode_equal(0o710, self.os.stat(dir2).st_mode) def test_makedirs_umask_applied(self): """makedirs creates a directories with umask applied.""" self.check_posix_only() self.os.umask(0o22) self.os.makedirs(self.make_path('p1', 'dir1')) self.assert_mode_equal( 0o755, self.os.stat(self.make_path('p1')).st_mode) self.assert_mode_equal( 0o755, self.os.stat(self.make_path('p1', 'dir1')).st_mode) self.os.umask(0o67) self.os.makedirs(self.make_path('p2', 'dir2')) self.assert_mode_equal( 0o710, self.os.stat(self.make_path('p2')).st_mode) self.assert_mode_equal( 0o710, self.os.stat(self.make_path('p2', 'dir2')).st_mode) def test_mknod_umask_applied(self): """mkdir creates a device with umask applied.""" # skipping MacOs due to mknod permission issues self.check_linux_only() self.os.umask(0o22) node1 = self.make_path('nod1') self.os.mknod(node1, stat.S_IFREG | 0o666) self.assert_mode_equal(0o644, self.os.stat(node1).st_mode) self.os.umask(0o27) node2 = self.make_path('nod2') self.os.mknod(node2, stat.S_IFREG | 0o666) self.assert_mode_equal(0o640, self.os.stat(node2).st_mode) def test_open_umask_applied(self): """open creates a file with umask applied.""" self.check_posix_only() self.os.umask(0o22) file1 = self.make_path('file1') self.open(file1, 'w').close() self.assert_mode_equal(0o644, self.os.stat(file1).st_mode) self.os.umask(0o27) file2 = self.make_path('file2') self.open(file2, 'w').close() self.assert_mode_equal(0o640, self.os.stat(file2).st_mode) class RealOsModuleTest(FakeOsModuleTest): def use_real_fs(self): return True class FakeOsModuleTestCaseInsensitiveFS(FakeOsModuleTestBase): def setUp(self): super(FakeOsModuleTestCaseInsensitiveFS, self).setUp() self.check_case_insensitive_fs() self.rwx = self.os.R_OK | self.os.W_OK | self.os.X_OK self.rw = self.os.R_OK | self.os.W_OK def test_chdir_fails_non_directory(self): """chdir should raise OSError if the target is not a directory.""" filename = self.make_path('foo', 'bar') self.create_file(filename) filename1 = self.make_path('Foo', 'Bar') self.assert_raises_os_error( self.not_dir_error(), self.os.chdir, filename1) def test_listdir_returns_list(self): directory_root = self.make_path('xyzzy') self.os.mkdir(directory_root) directory = self.os.path.join(directory_root, 'bug') self.os.mkdir(directory) directory_upper = self.make_path('XYZZY', 'BUG') self.create_file(self.make_path(directory, 'foo')) self.assertEqual(['foo'], self.os.listdir(directory_upper)) def test_listdir_on_symlink(self): self.skip_if_symlink_not_supported() directory = self.make_path('xyzzy') files = ['foo', 'bar', 'baz'] for f in files: self.create_file(self.make_path(directory, f)) self.create_symlink(self.make_path('symlink'), self.make_path('xyzzy')) files.sort() self.assertEqual(files, sorted(self.os.listdir(self.make_path('SymLink')))) def test_fdopen_mode(self): self.skip_real_fs() file_path1 = self.make_path('some_file1') file_path2 = self.make_path('Some_File1') file_path3 = self.make_path('SOME_file1') self.create_file(file_path1, contents='contents here1') self.os.chmod(file_path2, (stat.S_IFREG | 0o666) ^ stat.S_IWRITE) fake_file1 = self.open(file_path3, 'r') fileno1 = fake_file1.fileno() self.os.fdopen(fileno1) self.os.fdopen(fileno1, 'r') exception = OSError if self.is_python2 else IOError if not is_root(): self.assertRaises(exception, self.os.fdopen, fileno1, 'w') else: self.os.fdopen(fileno1, 'w') def test_stat(self): directory = self.make_path('xyzzy') directory1 = self.make_path('XYZZY') file_path = self.os.path.join(directory, 'plugh') self.create_file(file_path, contents='ABCDE') self.assertTrue(stat.S_IFDIR & self.os.stat(directory1)[stat.ST_MODE]) file_path1 = self.os.path.join(directory1, 'Plugh') self.assertTrue(stat.S_IFREG & self.os.stat(file_path1)[stat.ST_MODE]) self.assertTrue(stat.S_IFREG & self.os.stat(file_path1).st_mode) self.assertEqual(5, self.os.stat(file_path1)[stat.ST_SIZE]) @unittest.skipIf(sys.version_info < (3, 3), 'follow_symlinks new in Python 3.3') def test_stat_no_follow_symlinks_posix(self): """Test that stat with follow_symlinks=False behaves like lstat.""" self.check_posix_only() directory = self.make_path('xyzzy') base_name = 'plugh' file_contents = 'frobozz' # Just make sure we didn't accidentally make our test data meaningless. self.assertNotEqual(len(base_name), len(file_contents)) file_path = self.os.path.join(directory, base_name) link_path = self.os.path.join(directory, 'link') self.create_file(file_path, contents=file_contents) self.create_symlink(link_path, base_name) self.assertEqual(len(file_contents), self.os.stat( file_path.upper(), follow_symlinks=False)[stat.ST_SIZE]) self.assertEqual(len(base_name), self.os.stat( link_path.upper(), follow_symlinks=False)[stat.ST_SIZE]) def test_lstat_posix(self): self.check_posix_only() directory = self.make_path('xyzzy') base_name = 'plugh' file_contents = 'frobozz' # Just make sure we didn't accidentally make our test data meaningless. self.assertNotEqual(len(base_name), len(file_contents)) file_path = self.os.path.join(directory, base_name) link_path = self.os.path.join(directory, 'link') self.create_file(file_path, contents=file_contents) self.create_symlink(link_path, base_name) self.assertEqual(len(file_contents), self.os.lstat(file_path.upper())[stat.ST_SIZE]) self.assertEqual(len(base_name), self.os.lstat(link_path.upper())[stat.ST_SIZE]) def test_readlink(self): self.skip_if_symlink_not_supported() link_path = self.make_path('foo', 'bar', 'baz') target = self.make_path('tarJAY') self.create_symlink(link_path, target) self.assertEqual(self.os.readlink(link_path.upper()), target) def check_readlink_raises_if_path_not_a_link(self): file_path = self.make_path('foo', 'bar', 'eleventyone') self.create_file(file_path) self.assert_raises_os_error(errno.EINVAL, self.os.readlink, file_path.upper()) def test_readlink_raises_if_path_not_a_link_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() self.check_readlink_raises_if_path_not_a_link() def test_readlink_raises_if_path_not_a_link_posix(self): self.check_posix_only() self.check_readlink_raises_if_path_not_a_link() def check_readlink_raises_if_path_has_file(self, error_subtype): self.create_file(self.make_path('a_file')) file_path = self.make_path('a_file', 'foo') self.assert_raises_os_error(error_subtype, self.os.readlink, file_path.upper()) file_path = self.make_path('a_file', 'foo', 'bar') self.assert_raises_os_error(error_subtype, self.os.readlink, file_path.upper()) def test_readlink_raises_if_path_has_file_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() self.check_readlink_raises_if_path_has_file(errno.ENOENT) def test_readlink_raises_if_path_has_file_posix(self): self.check_posix_only() self.check_readlink_raises_if_path_has_file(errno.ENOTDIR) def test_readlink_with_links_in_path(self): self.skip_if_symlink_not_supported() self.create_symlink(self.make_path('meyer', 'lemon', 'pie'), self.make_path('yum')) self.create_symlink(self.make_path('geo', 'metro'), self.make_path('Meyer')) self.assertEqual(self.make_path('yum'), self.os.readlink( self.make_path('Geo', 'Metro', 'Lemon', 'Pie'))) def test_readlink_with_chained_links_in_path(self): self.skip_if_symlink_not_supported() self.create_symlink(self.make_path( 'eastern', 'european', 'wolfhounds', 'chase'), self.make_path('cats')) self.create_symlink(self.make_path('russian'), self.make_path('Eastern', 'European')) self.create_symlink(self.make_path('dogs'), self.make_path('Russian', 'Wolfhounds')) self.assertEqual(self.make_path('cats'), self.os.readlink(self.make_path('DOGS', 'Chase'))) def check_remove_dir(self, dir_error): directory = self.make_path('xyzzy') dir_path = self.os.path.join(directory, 'plugh') self.create_dir(dir_path) dir_path = dir_path.upper() self.assertTrue(self.os.path.exists(dir_path.upper())) self.assert_raises_os_error(dir_error, self.os.remove, dir_path) self.assertTrue(self.os.path.exists(dir_path)) self.os.chdir(directory) self.assert_raises_os_error(dir_error, self.os.remove, dir_path) self.assertTrue(self.os.path.exists(dir_path)) self.assert_raises_os_error(errno.ENOENT, self.os.remove, '/Plugh') def test_remove_dir_mac_os(self): self.check_macos_only() self.check_remove_dir(errno.EPERM) def test_remove_dir_windows(self): self.check_windows_only() self.check_remove_dir(errno.EACCES) def test_remove_file(self): directory = self.make_path('zzy') file_path = self.os.path.join(directory, 'plugh') self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path.upper())) self.os.remove(file_path.upper()) self.assertFalse(self.os.path.exists(file_path)) def test_remove_file_no_directory(self): directory = self.make_path('zzy') file_name = 'plugh' file_path = self.os.path.join(directory, file_name) self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.os.chdir(directory.upper()) self.os.remove(file_name.upper()) self.assertFalse(self.os.path.exists(file_path)) def test_remove_open_file_fails_under_windows(self): self.check_windows_only() path = self.make_path('foo', 'bar') self.create_file(path) with self.open(path, 'r'): self.assert_raises_os_error(errno.EACCES, self.os.remove, path.upper()) self.assertTrue(self.os.path.exists(path)) def test_remove_open_file_possible_under_posix(self): self.check_posix_only() path = self.make_path('foo', 'bar') self.create_file(path) self.open(path, 'r') self.os.remove(path.upper()) self.assertFalse(self.os.path.exists(path)) def test_remove_file_relative_path(self): self.skip_real_fs() original_dir = self.os.getcwd() directory = self.make_path('zzy') subdirectory = self.os.path.join(directory, 'zzy') file_name = 'plugh' file_path = self.os.path.join(directory, file_name) file_path_relative = self.os.path.join('..', file_name) self.create_file(file_path.upper()) self.assertTrue(self.os.path.exists(file_path)) self.create_dir(subdirectory) self.assertTrue(self.os.path.exists(subdirectory)) self.os.chdir(subdirectory.upper()) self.os.remove(file_path_relative.upper()) self.assertFalse(self.os.path.exists(file_path_relative)) self.os.chdir(original_dir.upper()) self.assertFalse(self.os.path.exists(file_path)) def check_remove_dir_raises_error(self, dir_error): directory = self.make_path('zzy') self.create_dir(directory) self.assert_raises_os_error(dir_error, self.os.remove, directory.upper()) def test_remove_dir_raises_error_mac_os(self): self.check_macos_only() self.check_remove_dir_raises_error(errno.EPERM) def test_remove_dir_raises_error_windows(self): self.check_windows_only() self.check_remove_dir_raises_error(errno.EACCES) def test_remove_symlink_to_dir(self): self.skip_if_symlink_not_supported() directory = self.make_path('zzy') link = self.make_path('link_to_dir') self.create_dir(directory) self.os.symlink(directory, link) self.assertTrue(self.os.path.exists(directory)) self.assertTrue(self.os.path.exists(link)) self.os.remove(link.upper()) self.assertTrue(self.os.path.exists(directory)) self.assertFalse(self.os.path.exists(link)) def test_rename_dir_to_symlink_posix(self): self.check_posix_only() link_path = self.make_path('link') dir_path = self.make_path('dir') link_target = self.os.path.join(dir_path, 'link_target') self.create_dir(dir_path) self.os.symlink(link_target.upper(), link_path.upper()) self.assert_raises_os_error(errno.ENOTDIR, self.os.rename, dir_path, link_path) def test_rename_dir_to_symlink_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() link_path = self.make_path('link') dir_path = self.make_path('dir') link_target = self.os.path.join(dir_path, 'link_target') self.create_dir(dir_path) self.os.symlink(link_target.upper(), link_path.upper()) self.assert_raises_os_error(errno.EEXIST, self.os.rename, dir_path, link_path) def test_rename_dir_to_existing_dir(self): # Regression test for #317 self.check_posix_only() dest_dir_path = self.make_path('Dest') new_dest_dir_path = self.make_path('dest') self.os.mkdir(dest_dir_path) source_dir_path = self.make_path('src') self.os.mkdir(source_dir_path) self.os.rename(source_dir_path, new_dest_dir_path) self.assertEqual(['dest'], self.os.listdir(self.base_path)) def test_rename_file_to_symlink(self): self.check_posix_only() link_path = self.make_path('file_link') file_path = self.make_path('file') self.os.symlink(file_path, link_path) self.create_file(file_path) self.os.rename(file_path.upper(), link_path) self.assertFalse(self.os.path.exists(file_path)) self.assertTrue(self.os.path.exists(link_path.upper())) self.assertTrue(self.os.path.isfile(link_path.upper())) def test_rename_symlink_to_symlink(self): self.check_posix_only() base_path = self.make_path('foo', 'bar') self.create_dir(base_path) link_path1 = self.os.path.join(base_path, 'link1') link_path2 = self.os.path.join(base_path, 'link2') self.os.symlink(base_path.upper(), link_path1) self.os.symlink(base_path, link_path2) self.os.rename(link_path1.upper(), link_path2.upper()) self.assertFalse(self.os.path.exists(link_path1)) self.assertTrue(self.os.path.exists(link_path2)) def test_rename_symlink_to_symlink_for_parent_raises(self): self.check_posix_only() dir_link = self.make_path('dir_link') dir_path = self.make_path('dir') dir_in_dir_path = self.os.path.join(dir_link, 'inner_dir') self.create_dir(dir_path) self.os.symlink(dir_path.upper(), dir_link) self.create_dir(dir_in_dir_path) self.assert_raises_os_error(errno.EINVAL, self.os.rename, dir_path, dir_in_dir_path.upper()) def test_rename_directory_to_linked_dir(self): # Regression test for #314 self.skip_if_symlink_not_supported() link_path = self.make_path('link') self.os.symlink(self.base_path, link_path) link_subdir = self.os.path.join(link_path, 'dir') dir_path = self.make_path('Dir') self.os.mkdir(dir_path) self.os.rename(dir_path, link_subdir) self.assertEqual(['dir', 'link'], sorted(self.os.listdir(self.base_path))) def test_recursive_rename_raises(self): self.check_posix_only() base_path = self.make_path('foo', 'bar') self.create_dir(base_path) new_path = self.os.path.join(base_path, 'new_dir') self.assert_raises_os_error(errno.EINVAL, self.os.rename, base_path.upper(), new_path) def test_rename_with_target_parent_file_raises_posix(self): self.check_posix_only() file_path = self.make_path('foo', 'baz') self.create_file(file_path) self.assert_raises_os_error(errno.ENOTDIR, self.os.rename, file_path, file_path.upper() + '/new') def test_rename_with_target_parent_file_raises_windows(self): self.check_windows_only() file_path = self.make_path('foo', 'baz') self.create_file(file_path) self.assert_raises_os_error( errno.EACCES, self.os.rename, file_path, self.os.path.join(file_path.upper(), 'new')) def test_rename_looping_symlink(self): # Regression test for #315 self.skip_if_symlink_not_supported() path_lower = self.make_path('baz') path_upper = self.make_path('BAZ') self.os.symlink(path_lower, path_upper) self.os.rename(path_upper, path_lower) self.assertEqual(['baz'], self.os.listdir(self.base_path)) def test_rename_symlink_to_source(self): self.check_posix_only() base_path = self.make_path('foo') link_path = self.os.path.join(base_path, 'slink') file_path = self.os.path.join(base_path, 'file') self.create_file(file_path) self.os.symlink(file_path, link_path) self.os.rename(link_path.upper(), file_path.upper()) self.assertFalse(self.os.path.exists(file_path)) def test_rename_symlink_to_dir_raises(self): self.check_posix_only() base_path = self.make_path('foo', 'bar') link_path = self.os.path.join(base_path, 'dir_link') dir_path = self.os.path.join(base_path, 'dir') self.create_dir(dir_path) self.os.symlink(dir_path, link_path.upper()) self.assert_raises_os_error(errno.EISDIR, self.os.rename, link_path, dir_path.upper()) def test_rename_broken_symlink(self): self.check_posix_only() base_path = self.make_path('foo') self.create_dir(base_path) link_path = self.os.path.join(base_path, 'slink') file_path = self.os.path.join(base_path, 'file') self.os.symlink(file_path.upper(), link_path) self.os.rename(link_path.upper(), file_path) self.assertFalse(self.os.path.exists(file_path)) self.assertTrue(self.os.path.lexists(file_path)) self.assertFalse(self.os.path.exists(link_path)) def test_change_case_in_case_insensitive_file_system(self): """Can use `rename()` to change filename case in a case-insensitive file system.""" old_file_path = self.make_path('fileName') new_file_path = self.make_path('FileNAME') self.create_file(old_file_path, contents='test contents') self.assertEqual(['fileName'], self.os.listdir(self.base_path)) self.os.rename(old_file_path, new_file_path) self.assertTrue(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.assertEqual(['FileNAME'], self.os.listdir(self.base_path)) def test_rename_symlink_with_changed_case(self): # Regression test for #313 self.skip_if_symlink_not_supported() link_path = self.make_path('link') self.os.symlink(self.base_path, link_path) link_path = self.os.path.join(link_path, 'link') link_path_upper = self.make_path('link', 'LINK') self.os.rename(link_path_upper, link_path) def test_rename_directory(self): """Can rename a directory to an unused name.""" for old_path, new_path in [('wxyyw', 'xyzzy'), ('abccb', 'cdeed')]: old_path = self.make_path(old_path) new_path = self.make_path(new_path) self.create_file(self.os.path.join(old_path, 'plugh'), contents='test') self.assertTrue(self.os.path.exists(old_path)) self.assertFalse(self.os.path.exists(new_path)) self.os.rename(old_path.upper(), new_path.upper()) self.assertFalse(self.os.path.exists(old_path)) self.assertTrue(self.os.path.exists(new_path)) self.check_contents(self.os.path.join(new_path, 'plugh'), 'test') if not self.use_real_fs(): self.assertEqual(3, self.filesystem.get_object(new_path).st_nlink) def check_rename_directory_to_existing_file_raises(self, error_nr): dir_path = self.make_path('dir') file_path = self.make_path('file') self.create_dir(dir_path) self.create_file(file_path) self.assert_raises_os_error(error_nr, self.os.rename, dir_path, file_path.upper()) def test_rename_directory_to_existing_file_raises_posix(self): self.check_posix_only() self.check_rename_directory_to_existing_file_raises(errno.ENOTDIR) def test_rename_directory_to_existing_file_raises_windows(self): self.check_windows_only() self.check_rename_directory_to_existing_file_raises(errno.EEXIST) def test_rename_to_existing_directory_should_raise_under_windows(self): """Renaming to an existing directory raises OSError under Windows.""" self.check_windows_only() old_path = self.make_path('foo', 'bar') new_path = self.make_path('foo', 'baz') self.create_dir(old_path) self.create_dir(new_path) self.assert_raises_os_error(errno.EEXIST, self.os.rename, old_path.upper(), new_path.upper()) def test_rename_to_a_hardlink_of_same_file_should_do_nothing(self): self.skip_real_fs_failure(skip_posix=False) self.skip_if_symlink_not_supported() file_path = self.make_path('dir', 'file') self.create_file(file_path) link_path = self.make_path('link') self.os.link(file_path.upper(), link_path) self.os.rename(file_path, link_path.upper()) self.assertTrue(self.os.path.exists(file_path)) self.assertTrue(self.os.path.exists(link_path)) def test_rename_with_incorrect_source_case(self): # Regression test for #308 base_path = self.make_path('foo') path0 = self.os.path.join(base_path, 'bar') path1 = self.os.path.join(base_path, 'Bar') self.create_dir(path0) self.os.rename(path1, path0) self.assertTrue(self.os.path.exists(path0)) def test_rename_symlink_to_other_case_does_nothing_in_mac_os(self): # Regression test for #318 self.check_macos_only() path0 = self.make_path("beta") self.os.symlink(self.base_path, path0) path0 = self.make_path("beta", "Beta") path1 = self.make_path("Beta") self.os.rename(path0, path1) self.assertEqual(['beta'], sorted(self.os.listdir(path0))) def test_rename_symlink_to_other_case_works_in_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() path0 = self.make_path("beta") self.os.symlink(self.base_path, path0) path0 = self.make_path("beta", "Beta") path1 = self.make_path("Beta") self.os.rename(path0, path1) self.assertEqual(['Beta'], sorted(self.os.listdir(path0))) def test_stat_with_mixed_case(self): # Regression test for #310 self.skip_if_symlink_not_supported() base_path = self.make_path('foo') path = self.os.path.join(base_path, 'bar') self.create_dir(path) path = self.os.path.join(path, 'Bar') self.os.symlink(base_path, path) path = self.os.path.join(path, 'Bar') # used to raise self.os.stat(path) def test_hardlink_works_with_symlink(self): self.check_posix_only() base_path = self.make_path('foo') self.create_dir(base_path) symlink_path = self.os.path.join(base_path, 'slink') self.os.symlink(base_path.upper(), symlink_path) file_path = self.os.path.join(base_path, 'slink', 'beta') self.create_file(file_path) link_path = self.os.path.join(base_path, 'Slink', 'gamma') self.os.link(file_path, link_path) self.assertTrue(self.os.path.exists(link_path)) @unittest.skipIf(sys.version_info < (3, 3), 'replace is new in Python 3.3') def test_replace_existing_directory_should_raise_under_windows(self): """Renaming to an existing directory raises OSError under Windows.""" self.check_windows_only() old_path = self.make_path('foo', 'bar') new_path = self.make_path('foo', 'baz') self.create_dir(old_path) self.create_dir(new_path) self.assert_raises_os_error(errno.EACCES, self.os.replace, old_path, new_path.upper()) def test_rename_to_existing_directory_under_posix(self): """Renaming to an existing directory changes the existing directory under Posix.""" self.check_posix_only() old_path = self.make_path('foo', 'bar') new_path = self.make_path('xyzzy') self.create_dir(self.os.path.join(old_path, 'sub')) self.create_dir(new_path) self.os.rename(old_path.upper(), new_path.upper()) self.assertTrue( self.os.path.exists(self.os.path.join(new_path, 'sub'))) self.assertFalse(self.os.path.exists(old_path)) def test_rename_file_to_existing_directory_raises_under_posix(self): self.check_posix_only() file_path = self.make_path('foo', 'bar', 'baz') new_path = self.make_path('xyzzy') self.create_file(file_path) self.create_dir(new_path) self.assert_raises_os_error(errno.EISDIR, self.os.rename, file_path.upper(), new_path.upper()) def test_rename_to_existent_file_posix(self): """Can rename a file to a used name under Unix.""" self.check_posix_only() directory = self.make_path('xyzzy') old_file_path = self.os.path.join(directory, 'plugh_old') new_file_path = self.os.path.join(directory, 'plugh_new') self.create_file(old_file_path, contents='test contents 1') self.create_file(new_file_path, contents='test contents 2') self.assertTrue(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.os.rename(old_file_path.upper(), new_file_path.upper()) self.assertFalse(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.check_contents(new_file_path, 'test contents 1') def test_rename_to_existent_file_windows(self): """Renaming a file to a used name raises OSError under Windows.""" self.check_windows_only() directory = self.make_path('xyzzy') old_file_path = self.os.path.join(directory, 'plugh_old') new_file_path = self.os.path.join(directory, 'plugh_new') self.create_file(old_file_path, contents='test contents 1') self.create_file(new_file_path, contents='test contents 2') self.assertTrue(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.assert_raises_os_error(errno.EEXIST, self.os.rename, old_file_path.upper(), new_file_path.upper()) @unittest.skipIf(sys.version_info < (3, 3), 'replace is new in Python 3.3') def test_replace_to_existent_file(self): """Replaces an existing file (does not work with `rename()` under Windows).""" directory = self.make_path('xyzzy') old_file_path = self.os.path.join(directory, 'plugh_old') new_file_path = self.os.path.join(directory, 'plugh_new') self.create_file(old_file_path, contents='test contents 1') self.create_file(new_file_path, contents='test contents 2') self.assertTrue(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.os.replace(old_file_path.upper(), new_file_path.upper()) self.assertFalse(self.os.path.exists(old_file_path)) self.assertTrue(self.os.path.exists(new_file_path)) self.check_contents(new_file_path, 'test contents 1') def test_rename_to_nonexistent_dir(self): """Can rename a file to a name in a nonexistent dir.""" directory = self.make_path('xyzzy') old_file_path = self.os.path.join(directory, 'plugh_old') new_file_path = self.os.path.join( directory, 'no_such_path', 'plugh_new') self.create_file(old_file_path, contents='test contents') self.assertTrue(self.os.path.exists(old_file_path)) self.assertFalse(self.os.path.exists(new_file_path)) self.assert_raises_os_error(errno.ENOENT, self.os.rename, old_file_path.upper(), new_file_path.upper()) self.assertTrue(self.os.path.exists(old_file_path)) self.assertFalse(self.os.path.exists(new_file_path)) self.check_contents(old_file_path, 'test contents') def check_rename_case_only_with_symlink_parent(self): # Regression test for #319 self.os.symlink(self.base_path, self.make_path('link')) dir_upper = self.make_path('link', 'Alpha') self.os.mkdir(dir_upper) dir_lower = self.make_path('alpha') self.os.rename(dir_upper, dir_lower) self.assertEqual(['alpha', 'link'], sorted(self.os.listdir(self.base_path))) def test_rename_case_only_with_symlink_parent_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() self.check_rename_case_only_with_symlink_parent() def test_rename_case_only_with_symlink_parent_macos(self): self.check_macos_only() self.check_rename_case_only_with_symlink_parent() def test_rename_dir(self): """Test a rename of a directory.""" directory = self.make_path('xyzzy') before_dir = self.os.path.join(directory, 'before') before_file = self.os.path.join(directory, 'before', 'file') after_dir = self.os.path.join(directory, 'after') after_file = self.os.path.join(directory, 'after', 'file') self.create_dir(before_dir) self.create_file(before_file, contents='payload') self.assertTrue(self.os.path.exists(before_dir.upper())) self.assertTrue(self.os.path.exists(before_file.upper())) self.assertFalse(self.os.path.exists(after_dir.upper())) self.assertFalse(self.os.path.exists(after_file.upper())) self.os.rename(before_dir.upper(), after_dir) self.assertFalse(self.os.path.exists(before_dir.upper())) self.assertFalse(self.os.path.exists(before_file.upper())) self.assertTrue(self.os.path.exists(after_dir.upper())) self.assertTrue(self.os.path.exists(after_file.upper())) self.check_contents(after_file, 'payload') def test_rename_same_filenames(self): """Test renaming when old and new names are the same.""" directory = self.make_path('xyzzy') file_contents = 'Spam eggs' file_path = self.os.path.join(directory, 'eggs') self.create_file(file_path, contents=file_contents) self.os.rename(file_path, file_path.upper()) self.check_contents(file_path, file_contents) def test_rmdir(self): """Can remove a directory.""" directory = self.make_path('xyzzy') sub_dir = self.make_path('xyzzy', 'abccd') other_dir = self.make_path('xyzzy', 'cdeed') self.create_dir(directory) self.assertTrue(self.os.path.exists(directory)) self.os.rmdir(directory) self.assertFalse(self.os.path.exists(directory)) self.create_dir(sub_dir) self.create_dir(other_dir) self.os.chdir(sub_dir) self.os.rmdir('../CDEED') self.assertFalse(self.os.path.exists(other_dir)) self.os.chdir('..') self.os.rmdir('AbcCd') self.assertFalse(self.os.path.exists(sub_dir)) def test_rmdir_via_symlink(self): self.check_windows_only() self.skip_if_symlink_not_supported() base_path = self.make_path('foo', 'bar') dir_path = self.os.path.join(base_path, 'alpha') self.create_dir(dir_path) link_path = self.os.path.join(base_path, 'beta') self.os.symlink(base_path, link_path) self.os.rmdir(link_path + '/Alpha') self.assertFalse(self.os.path.exists(dir_path)) def test_remove_dirs_with_non_top_symlink_succeeds(self): self.check_posix_only() dir_path = self.make_path('dir') dir_link = self.make_path('dir_link') self.create_dir(dir_path) self.os.symlink(dir_path, dir_link) dir_in_dir = self.os.path.join(dir_link, 'dir2') self.create_dir(dir_in_dir) self.os.removedirs(dir_in_dir.upper()) self.assertFalse(self.os.path.exists(dir_in_dir)) # ensure that the symlink is not removed self.assertTrue(self.os.path.exists(dir_link)) def test_mkdir_raises_on_symlink_in_posix(self): self.check_posix_only() base_path = self.make_path('foo', 'bar') link_path = self.os.path.join(base_path, 'link_to_dir') dir_path = self.os.path.join(base_path, 'dir') self.create_dir(dir_path) self.os.symlink(dir_path.upper(), link_path.upper()) self.assert_raises_os_error(errno.ENOTDIR, self.os.rmdir, link_path) def test_mkdir_removes_symlink_in_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() base_path = self.make_path('foo', 'bar') link_path = self.os.path.join(base_path, 'link_to_dir') dir_path = self.os.path.join(base_path, 'dir') self.create_dir(dir_path) self.os.symlink(dir_path.upper(), link_path.upper()) self.os.rmdir(link_path) self.assertFalse(self.os.path.exists(link_path)) self.assertTrue(self.os.path.exists(dir_path)) def test_mkdir_raises_if_directory_exists(self): """mkdir raises exception if directory already exists.""" directory = self.make_path('xyzzy') self.create_dir(directory) self.assertTrue(self.os.path.exists(directory)) self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, directory.upper()) def test_mkdir_raises_if_file_exists(self): """mkdir raises exception if name already exists as a file.""" directory = self.make_path('xyzzy') file_path = self.os.path.join(directory, 'plugh') self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, file_path.upper()) def test_mkdir_raises_if_symlink_exists(self): # Regression test for #309 self.skip_if_symlink_not_supported() path1 = self.make_path('baz') self.os.symlink(path1, path1) path2 = self.make_path('Baz') self.assert_raises_os_error(errno.EEXIST, self.os.mkdir, path2) def check_mkdir_raises_if_parent_is_file(self, error_type): """mkdir raises exception if name already exists as a file.""" directory = self.make_path('xyzzy') file_path = self.os.path.join(directory, 'plugh') self.create_file(file_path) self.assert_raises_os_error(error_type, self.os.mkdir, self.os.path.join(file_path.upper(), 'ff')) def test_mkdir_raises_if_parent_is_file_posix(self): self.check_posix_only() self.check_mkdir_raises_if_parent_is_file(errno.ENOTDIR) def test_mkdir_raises_if_parent_is_file_windows(self): self.check_windows_only() self.check_mkdir_raises_if_parent_is_file(errno.ENOENT) def test_makedirs(self): """makedirs can create a directory even if parent does not exist.""" parent = self.make_path('xyzzy') directory = self.os.path.join(parent, 'foo') self.assertFalse(self.os.path.exists(parent)) self.os.makedirs(directory.upper()) self.assertTrue(self.os.path.exists(directory)) def check_makedirs_raises_if_parent_is_file(self, error_type): """makedirs raises exception if a parent component exists as a file.""" file_path = self.make_path('xyzzy') directory = self.os.path.join(file_path, 'plugh') self.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.assert_raises_os_error(error_type, self.os.makedirs, directory.upper()) def test_makedirs_raises_if_parent_is_file_posix(self): self.check_posix_only() self.check_makedirs_raises_if_parent_is_file(errno.ENOTDIR) def test_makedirs_raises_if_parent_is_file_windows(self): self.check_windows_only() self.check_makedirs_raises_if_parent_is_file(errno.ENOENT) def test_makedirs_raises_if_parent_is_broken_link(self): self.check_posix_only() link_path = self.make_path('broken_link') self.os.symlink(self.make_path('bogus'), link_path) self.assert_raises_os_error(errno.ENOENT, self.os.makedirs, self.os.path.join(link_path.upper(), 'newdir')) @unittest.skipIf(sys.version_info < (3, 2), 'os.makedirs(exist_ok) argument new in version 3.2') def test_makedirs_exist_ok(self): """makedirs uses the exist_ok argument""" directory = self.make_path('xyzzy', 'foo') self.create_dir(directory) self.assertTrue(self.os.path.exists(directory)) self.assert_raises_os_error(errno.EEXIST, self.os.makedirs, directory.upper()) self.os.makedirs(directory.upper(), exist_ok=True) self.assertTrue(self.os.path.exists(directory)) # test fsync and fdatasync def test_fsync_pass(self): test_file_path = self.make_path('test_file') self.create_file(test_file_path, contents='dummy file contents') test_file = self.open(test_file_path.upper(), 'r+') test_fd = test_file.fileno() # Test that this doesn't raise anything self.os.fsync(test_fd) # And just for sanity, double-check that this still raises self.assert_raises_os_error(errno.EBADF, self.os.fsync, test_fd + 10) def test_chmod(self): # set up self.check_posix_only() self.skip_real_fs() path = self.make_path('some_file') self.createTestFile(path) # actual tests self.os.chmod(path.upper(), 0o6543) st = self.os.stat(path) self.assert_mode_equal(0o6543, st.st_mode) self.assertTrue(st.st_mode & stat.S_IFREG) self.assertFalse(st.st_mode & stat.S_IFDIR) def test_symlink(self): self.skip_if_symlink_not_supported() file_path = self.make_path('foo', 'bar', 'baz') self.create_dir(self.make_path('foo', 'bar')) self.os.symlink('bogus', file_path.upper()) self.assertTrue(self.os.path.lexists(file_path)) self.assertFalse(self.os.path.exists(file_path)) self.create_file(self.make_path('Foo', 'Bar', 'Bogus')) self.assertTrue(self.os.path.lexists(file_path)) self.assertTrue(self.os.path.exists(file_path)) # hard link related tests def test_link_delete(self): self.skip_if_symlink_not_supported() file1_path = self.make_path('test_file1') file2_path = self.make_path('test_file2') contents1 = 'abcdef' # Create file self.create_file(file1_path, contents=contents1) # link to second file self.os.link(file1_path.upper(), file2_path) # delete first file self.os.unlink(file1_path) # assert that second file exists, and its contents are the same self.assertTrue(self.os.path.exists(file2_path)) with self.open(file2_path.upper()) as f: self.assertEqual(f.read(), contents1) def test_link_is_existing_file(self): self.skip_if_symlink_not_supported() file_path = self.make_path('foo', 'bar') self.create_file(file_path) self.assert_raises_os_error(errno.EEXIST, self.os.link, file_path.upper(), file_path.upper()) def test_link_is_broken_symlink(self): # Regression test for #311 self.skip_if_symlink_not_supported() self.check_case_insensitive_fs() file_path = self.make_path('baz') self.create_file(file_path) path_lower = self.make_path('foo') self.os.symlink(path_lower, path_lower) path_upper = self.make_path('Foo') self.assert_raises_os_error(errno.EEXIST, self.os.link, file_path, path_upper) def test_link_with_changed_case(self): # Regression test for #312 self.skip_if_symlink_not_supported() self.check_case_insensitive_fs() link_path = self.make_path('link') self.os.symlink(self.base_path, link_path) link_path = self.os.path.join(link_path, 'Link') self.assertTrue(self.os.lstat(link_path)) class RealOsModuleTestCaseInsensitiveFS(FakeOsModuleTestCaseInsensitiveFS): def use_real_fs(self): return True class FakeOsModuleTimeTest(FakeOsModuleTestBase): def setUp(self): super(FakeOsModuleTimeTest, self).setUp() self.orig_time = time.time self.dummy_time = None self.setDummyTime(200) def tearDown(self): time.time = self.orig_time super(FakeOsModuleTimeTest, self).tearDown() def setDummyTime(self, start): self.dummy_time = DummyTime(start, 20) time.time = self.dummy_time def test_chmod_st_ctime(self): # set up file_path = 'some_file' self.filesystem.create_file(file_path) self.assertTrue(self.os.path.exists(file_path)) self.dummy_time.start() st = self.os.stat(file_path) self.assertEqual(200, st.st_ctime) # tests self.os.chmod(file_path, 0o765) st = self.os.stat(file_path) self.assertEqual(220, st.st_ctime) def test_utime_sets_current_time_if_args_is_none(self): # set up path = self.make_path('some_file') self.createTestFile(path) self.dummy_time.start() st = self.os.stat(path) # 200 is the current time established in setUp(). self.assertEqual(200, st.st_atime) self.assertEqual(200, st.st_mtime) # actual tests self.os.utime(path, None) st = self.os.stat(path) self.assertEqual(220, st.st_atime) self.assertEqual(220, st.st_mtime) def test_utime_sets_current_time_if_args_is_none_with_floats(self): # set up # we set os.stat_float_times() to False, so atime/ctime/mtime # are converted as ints (seconds since epoch) self.setDummyTime(200.9123) path = '/some_file' fake_filesystem.FakeOsModule.stat_float_times(False) self.createTestFile(path) self.dummy_time.start() st = self.os.stat(path) # 200 is the current time established above (if converted to int). self.assertEqual(200, st.st_atime) self.assertTrue(isinstance(st.st_atime, int)) self.assertEqual(200, st.st_mtime) self.assertTrue(isinstance(st.st_mtime, int)) if sys.version_info >= (3, 3): self.assertEqual(200912300000, st.st_atime_ns) self.assertEqual(200912300000, st.st_mtime_ns) self.assertEqual(200, st.st_mtime) # actual tests self.os.utime(path, None) st = self.os.stat(path) self.assertEqual(220, st.st_atime) self.assertTrue(isinstance(st.st_atime, int)) self.assertEqual(220, st.st_mtime) self.assertTrue(isinstance(st.st_mtime, int)) if sys.version_info >= (3, 3): self.assertEqual(220912300000, st.st_atime_ns) self.assertEqual(220912300000, st.st_mtime_ns) def test_utime_sets_current_time_if_args_is_none_with_floats_n_sec(self): fake_filesystem.FakeOsModule.stat_float_times(False) self.setDummyTime(200.9123) path = self.make_path('some_file') self.createTestFile(path) test_file = self.filesystem.get_object(path) self.dummy_time.start() st = self.os.stat(path) self.assertEqual(200, st.st_ctime) self.assertEqual(200, test_file.st_ctime) self.assertTrue(isinstance(st.st_ctime, int)) self.assertTrue(isinstance(test_file.st_ctime, int)) self.os.stat_float_times(True) # first time float time self.assertEqual(200, st.st_ctime) # st does not change self.assertEqual(200.9123, test_file.st_ctime) # but the file does self.assertTrue(isinstance(st.st_ctime, int)) self.assertTrue(isinstance(test_file.st_ctime, float)) self.os.stat_float_times(False) # reverting to int self.assertEqual(200, test_file.st_ctime) self.assertTrue(isinstance(test_file.st_ctime, int)) self.assertEqual(200, st.st_ctime) self.assertTrue(isinstance(st.st_ctime, int)) self.os.stat_float_times(True) st = self.os.stat(path) # 200.9123 not converted to int self.assertEqual(200.9123, test_file.st_atime, test_file.st_mtime) self.assertEqual(200.9123, st.st_atime, st.st_mtime) self.os.utime(path, None) st = self.os.stat(path) self.assertEqual(220.9123, st.st_atime) self.assertEqual(220.9123, st.st_mtime) def test_utime_sets_specified_time(self): # set up path = self.make_path('some_file') self.createTestFile(path) self.os.stat(path) # actual tests self.os.utime(path, (1, 2)) st = self.os.stat(path) self.assertEqual(1, st.st_atime) self.assertEqual(2, st.st_mtime) def test_utime_dir(self): # set up path = '/some_dir' self.createTestDirectory(path) # actual tests self.os.utime(path, (1.0, 2.0)) st = self.os.stat(path) self.assertEqual(1.0, st.st_atime) self.assertEqual(2.0, st.st_mtime) @unittest.skipIf(sys.version_info < (3, 3), 'follow_symlinks new in Python 3.3') def test_utime_follow_symlinks(self): path = self.make_path('some_file') self.createTestFile(path) link_path = '/link_to_some_file' self.filesystem.create_symlink(link_path, path) self.os.utime(link_path, (1, 2)) st = self.os.stat(link_path) self.assertEqual(1, st.st_atime) self.assertEqual(2, st.st_mtime) @unittest.skipIf(sys.version_info < (3, 3), 'follow_symlinks new in Python 3.3') def test_utime_no_follow_symlinks(self): path = self.make_path('some_file') self.createTestFile(path) link_path = '/link_to_some_file' self.filesystem.create_symlink(link_path, path) self.os.utime(link_path, (1, 2), follow_symlinks=False) st = self.os.stat(link_path) self.assertNotEqual(1, st.st_atime) self.assertNotEqual(2, st.st_mtime) st = self.os.stat(link_path, follow_symlinks=False) self.assertEqual(1, st.st_atime) self.assertEqual(2, st.st_mtime) def test_utime_non_existent(self): path = '/non/existent/file' self.assertFalse(self.os.path.exists(path)) self.assert_raises_os_error(errno.ENOENT, self.os.utime, path, (1, 2)) def test_utime_invalid_times_arg_raises(self): path = '/some_dir' self.createTestDirectory(path) # the error message differs with different Python versions # we don't expect the same message here self.assertRaises(TypeError, self.os.utime, path, (1, 2, 3)) self.assertRaises(TypeError, self.os.utime, path, (1, 'str')) @unittest.skipIf(sys.version_info < (3, 3), 'ns new in Python 3.3') def test_utime_sets_specified_time_in_ns(self): # set up path = self.make_path('some_file') self.createTestFile(path) self.dummy_time.start() self.os.stat(path) # actual tests self.os.utime(path, ns=(200000000, 400000000)) st = self.os.stat(path) self.assertEqual(0.2, st.st_atime) self.assertEqual(0.4, st.st_mtime) @unittest.skipIf(sys.version_info < (3, 3), 'ns new in Python 3.3') def test_utime_incorrect_ns_argument_raises(self): file_path = 'some_file' self.filesystem.create_file(file_path) self.assertRaises(TypeError, self.os.utime, file_path, ns=200000000) self.assertRaises(TypeError, self.os.utime, file_path, ns=('a', 'b')) self.assertRaises(ValueError, self.os.utime, file_path, times=(1, 2), ns=(100, 200)) @unittest.skipIf(sys.version_info < (3, 3), 'file descriptor as path new in Python 3.3') def test_utime_uses_open_fd_as_path(self): if os.utime not in os.supports_fd: self.skip_real_fs() self.assert_raises_os_error(errno.EBADF, self.os.utime, 5, (1, 2)) path = self.make_path('some_file') self.createTestFile(path) with FakeFileOpen(self.filesystem)(path) as f: self.os.utime(f.filedes, times=(1, 2)) st = self.os.stat(path) self.assertEqual(1, st.st_atime) self.assertEqual(2, st.st_mtime) class FakeOsModuleLowLevelFileOpTest(FakeOsModuleTestBase): """Test low level functions `os.open()`, `os.read()` and `os.write()`.""" def setUp(self): os.umask(0o022) super(FakeOsModuleLowLevelFileOpTest, self).setUp() def test_open_read_only(self): file_path = self.make_path('file1') self.create_file(file_path, contents=b'contents') file_des = self.os.open(file_path, os.O_RDONLY) self.assertEqual(b'contents', self.os.read(file_des, 8)) self.assert_raises_os_error(errno.EBADF, self.os.write, file_des, b'test') self.os.close(file_des) def test_open_read_only_write_zero_bytes_posix(self): self.check_posix_only() file_path = self.make_path('file1') self.create_file(file_path, contents=b'contents') file_des = self.os.open(file_path, os.O_RDONLY) self.assert_raises_os_error(errno.EBADF, self.os.write, file_des, b'test') self.os.close(file_des) def test_open_read_only_write_zero_bytes_windows(self): # under Windows, writing an empty string to a read only file # is not an error self.check_windows_only() file_path = self.make_path('file1') self.create_file(file_path, contents=b'contents') file_des = self.os.open(file_path, os.O_RDONLY) self.assertEqual(0, self.os.write(file_des, b'')) self.os.close(file_des) def test_open_write_only(self): file_path = self.make_path('file1') self.create_file(file_path, contents=b'contents') file_des = self.os.open(file_path, os.O_WRONLY) self.assertEqual(4, self.os.write(file_des, b'test')) self.check_contents(file_path, b'testents') self.os.close(file_des) def test_open_write_only_raises_on_read(self): file_path = self.make_path('file1') self.create_file(file_path, contents=b'contents') file_des = self.os.open(file_path, os.O_WRONLY) self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 5) self.os.close(file_des) file_des = self.os.open(file_path, os.O_WRONLY | os.O_TRUNC) self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 5) self.os.close(file_des) file_path2 = self.make_path('file2') file_des = self.os.open(file_path2, os.O_CREAT | os.O_WRONLY) self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 5) self.os.close(file_des) file_des = self.os.open(file_path2, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 5) self.os.close(file_des) def test_open_write_only_read_zero_bytes_posix(self): self.check_posix_only() file_path = self.make_path('file1') file_des = self.os.open(file_path, os.O_CREAT | os.O_WRONLY) self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 0) self.os.close(file_des) def test_open_write_only_read_zero_bytes_windows(self): # under Windows, reading 0 bytes from a write only file is not an error self.check_windows_only() file_path = self.make_path('file1') file_des = self.os.open(file_path, os.O_CREAT | os.O_WRONLY) self.assertEqual(b'', self.os.read(file_des, 0)) self.os.close(file_des) def test_open_read_write(self): file_path = self.make_path('file1') self.create_file(file_path, contents=b'contents') file_des = self.os.open(file_path, os.O_RDWR) self.assertEqual(4, self.os.write(file_des, b'test')) self.check_contents(file_path, b'testents') self.os.close(file_des) def test_open_create_is_read_only(self): file_path = self.make_path('file1') file_des = self.os.open(file_path, os.O_CREAT) self.assertEqual(b'', self.os.read(file_des, 1)) self.assert_raises_os_error(errno.EBADF, self.os.write, file_des, b'foo') self.os.close(file_des) def test_open_create_truncate_is_read_only(self): file_path = self.make_path('file1') file_des = self.os.open(file_path, os.O_CREAT | os.O_TRUNC) self.assertEqual(b'', self.os.read(file_des, 1)) self.assert_raises_os_error(errno.EBADF, self.os.write, file_des, b'foo') self.os.close(file_des) def test_open_raises_if_does_not_exist(self): file_path = self.make_path('file1') self.assert_raises_os_error(errno.ENOENT, self.os.open, file_path, os.O_RDONLY) self.assert_raises_os_error(errno.ENOENT, self.os.open, file_path, os.O_WRONLY) self.assert_raises_os_error(errno.ENOENT, self.os.open, file_path, os.O_RDWR) def test_exclusive_open_raises_without_create_mode(self): self.skip_real_fs() file_path = self.make_path('file1') self.assertRaises(NotImplementedError, self.os.open, file_path, os.O_EXCL) self.assertRaises(NotImplementedError, self.os.open, file_path, os.O_EXCL | os.O_WRONLY) self.assertRaises(NotImplementedError, self.os.open, file_path, os.O_EXCL | os.O_RDWR) self.assertRaises(NotImplementedError, self.os.open, file_path, os.O_EXCL | os.O_TRUNC | os.O_APPEND) def test_open_raises_if_parent_does_not_exist(self): path = self.make_path('alpha', 'alpha') self.assert_raises_os_error(errno.ENOENT, self.os.open, path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) def test_open_truncate(self): file_path = self.make_path('file1') self.create_file(file_path, contents=b'contents') file_des = self.os.open(file_path, os.O_RDWR | os.O_TRUNC) self.assertEqual(b'', self.os.read(file_des, 8)) self.assertEqual(4, self.os.write(file_des, b'test')) self.check_contents(file_path, b'test') self.os.close(file_des) @unittest.skipIf(not TestCase.is_windows, 'O_TEMPORARY only present in Windows') def test_temp_file(self): file_path = self.make_path('file1') fd = self.os.open(file_path, os.O_CREAT | os.O_RDWR | os.O_TEMPORARY) self.assertTrue(self.os.path.exists(file_path)) self.os.close(fd) self.assertFalse(self.os.path.exists(file_path)) def test_open_append(self): file_path = self.make_path('file1') self.create_file(file_path, contents=b'contents') file_des = self.os.open(file_path, os.O_WRONLY | os.O_APPEND) self.assertEqual(4, self.os.write(file_des, b'test')) self.check_contents(file_path, b'contentstest') self.os.close(file_des) def test_open_create(self): file_path = self.make_path('file1') file_des = self.os.open(file_path, os.O_RDWR | os.O_CREAT) self.assertTrue(self.os.path.exists(file_path)) self.assertEqual(4, self.os.write(file_des, b'test')) self.check_contents(file_path, 'test') self.os.close(file_des) def test_can_read_after_create_exclusive(self): self.check_posix_only() path1 = self.make_path('alpha') file_des = self.os.open(path1, os.O_CREAT | os.O_EXCL) self.assertEqual(b'', self.os.read(file_des, 0)) self.assert_raises_os_error(errno.EBADF, self.os.write, file_des, b'') self.os.close(file_des) def test_open_create_mode_posix(self): self.check_posix_only() file_path = self.make_path('file1') file_des = self.os.open(file_path, os.O_WRONLY | os.O_CREAT, 0o700) self.assertTrue(self.os.path.exists(file_path)) self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 5) self.assertEqual(4, self.os.write(file_des, b'test')) self.assert_mode_equal(0o700, self.os.stat(file_path).st_mode) self.os.close(file_des) def test_open_create_mode_windows(self): self.check_windows_only() file_path = self.make_path('file1') file_des = self.os.open(file_path, os.O_WRONLY | os.O_CREAT, 0o700) self.assertTrue(self.os.path.exists(file_path)) self.assert_raises_os_error(errno.EBADF, self.os.read, file_des, 5) self.assertEqual(4, self.os.write(file_des, b'test')) self.assert_mode_equal(0o666, self.os.stat(file_path).st_mode) self.os.close(file_des) def testOpenCreateMode444Windows(self): self.check_windows_only() file_path = self.make_path('file1') file_des = self.os.open(file_path, os.O_WRONLY | os.O_CREAT, 0o442) self.assert_mode_equal(0o444, self.os.stat(file_path).st_mode) self.os.close(file_des) def testOpenCreateMode666Windows(self): self.check_windows_only() file_path = self.make_path('file1') file_des = self.os.open(file_path, os.O_WRONLY | os.O_CREAT, 0o224) self.assert_mode_equal(0o666, self.os.stat(file_path).st_mode) self.os.close(file_des) @unittest.skipIf(sys.version_info < (3, 3), 'Exclusive mode new in Python 3.3') def test_open_exclusive(self): file_path = self.make_path('file1') file_des = self.os.open(file_path, os.O_RDWR | os.O_EXCL | os.O_CREAT) self.assertTrue(self.os.path.exists(file_path)) self.os.close(file_des) @unittest.skipIf(sys.version_info < (3, 3), 'Exclusive mode new in Python 3.3') def test_open_exclusive_raises_if_file_exists(self): file_path = self.make_path('file1') self.create_file(file_path, contents=b'contents') self.assert_raises_io_error(errno.EEXIST, self.os.open, file_path, os.O_RDWR | os.O_EXCL | os.O_CREAT) self.assert_raises_io_error(errno.EEXIST, self.os.open, file_path, os.O_RDWR | os.O_EXCL | os.O_CREAT) @unittest.skipIf(sys.version_info < (3, 3), 'Exclusive mode new in Python 3.3') def test_open_exclusive_raises_if_symlink_exists_in_posix(self): self.check_posix_only() link_path = self.make_path('link') link_target = self.make_path('link_target') self.os.symlink(link_target, link_path) self.assert_raises_os_error( errno.EEXIST, self.os.open, link_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC | os.O_EXCL) @unittest.skipIf(sys.version_info < (3, 3), 'Exclusive mode new in Python 3.3') def test_open_exclusive_if_symlink_exists_works_in_windows(self): self.check_windows_only() self.skip_if_symlink_not_supported() link_path = self.make_path('link') link_target = self.make_path('link_target') self.os.symlink(link_target, link_path) fd = self.os.open(link_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC | os.O_EXCL) self.os.close(fd) def test_open_directory_raises_under_windows(self): self.check_windows_only() dir_path = self.make_path('dir') self.create_dir(dir_path) self.assert_raises_os_error(errno.EACCES, self.os.open, dir_path, os.O_RDONLY) self.assert_raises_os_error(errno.EACCES, self.os.open, dir_path, os.O_WRONLY) self.assert_raises_os_error(errno.EACCES, self.os.open, dir_path, os.O_RDWR) def test_open_directory_for_writing_raises_under_posix(self): self.check_posix_only() dir_path = self.make_path('dir') self.create_dir(dir_path) self.assert_raises_os_error(errno.EISDIR, self.os.open, dir_path, os.O_WRONLY) self.assert_raises_os_error(errno.EISDIR, self.os.open, dir_path, os.O_RDWR) def test_open_directory_read_only_under_posix(self): self.check_posix_only() self.skip_real_fs() dir_path = self.make_path('dir') self.create_dir(dir_path) file_des = self.os.open(dir_path, os.O_RDONLY) self.assertEqual(3, file_des) def test_opening_existing_directory_in_creation_mode(self): self.check_linux_only() dir_path = self.make_path("alpha") self.os.mkdir(dir_path) self.assert_raises_os_error(errno.EISDIR, self.os.open, dir_path, os.O_CREAT) def test_writing_to_existing_directory(self): self.check_macos_only() dir_path = self.make_path("alpha") self.os.mkdir(dir_path) fd = self.os.open(dir_path, os.O_CREAT) self.assert_raises_os_error(errno.EBADF, self.os.write, fd, b'') def test_opening_existing_directory_in_write_mode(self): self.check_posix_only() dir_path = self.make_path("alpha") self.os.mkdir(dir_path) self.assert_raises_os_error(errno.EISDIR, self.os.open, dir_path, os.O_WRONLY) def test_open_mode_posix(self): self.check_posix_only() self.skip_real_fs() file_path = self.make_path('baz') file_des = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) stat0 = self.os.fstat(file_des) # not a really good test as this replicates the code, # but we don't know the umask at the test system self.assertEqual(0o100777 & ~self.os._umask(), stat0.st_mode) self.os.close(file_des) def test_open_mode_windows(self): self.check_windows_only() file_path = self.make_path('baz') file_des = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) stat0 = self.os.fstat(file_des) self.assertEqual(0o100666, stat0.st_mode) self.os.close(file_des) def test_write_read(self): file_path = self.make_path('file1') self.create_file(file_path, contents=b'orig contents') new_contents = b'1234567890abcdef' with self.open(file_path, 'wb') as fh: fileno = fh.fileno() self.assertEqual(len(new_contents), self.os.write(fileno, new_contents)) self.check_contents(file_path, new_contents) with self.open(file_path, 'rb') as fh: fileno = fh.fileno() self.assertEqual(b'', self.os.read(fileno, 0)) self.assertEqual(new_contents[0:2], self.os.read(fileno, 2)) self.assertEqual(new_contents[2:10], self.os.read(fileno, 8)) self.assertEqual(new_contents[10:], self.os.read(fileno, 100)) self.assertEqual(b'', self.os.read(fileno, 10)) self.assert_raises_os_error(errno.EBADF, self.os.write, fileno, new_contents) self.assert_raises_os_error(errno.EBADF, self.os.read, fileno, 10) def test_write_from_different_f_ds(self): # Regression test for #211 file_path = self.make_path('baz') fd0 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) fd1 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) self.os.write(fd0, b'aaaa') self.os.write(fd1, b'bb') self.assertEqual(4, self.os.path.getsize(file_path)) self.check_contents(file_path, b'bbaa') self.os.close(fd1) self.os.close(fd0) def test_write_from_different_fds_with_append(self): # Regression test for #268 file_path = self.make_path('baz') fd0 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) fd1 = self.os.open(file_path, os.O_WRONLY | os.O_APPEND) self.os.write(fd0, b'aaa') self.os.write(fd1, b'bbb') self.assertEqual(6, self.os.path.getsize(file_path)) self.check_contents(file_path, b'aaabbb') self.os.close(fd1) self.os.close(fd0) def test_read_only_read_after_write(self): # Regression test for #269 self.check_posix_only() file_path = self.make_path('foo', 'bar', 'baz') self.create_file(file_path, contents=b'test') fd0 = self.os.open(file_path, os.O_CREAT) fd1 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) self.assertEqual(b'', self.os.read(fd0, 0)) self.os.close(fd1) self.os.close(fd0) def test_read_after_closing_write_descriptor(self): # Regression test for #271 file_path = self.make_path('baz') fd0 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) fd1 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) fd2 = self.os.open(file_path, os.O_CREAT) self.os.write(fd1, b'abc') self.os.close(fd0) self.assertEqual(b'abc', self.os.read(fd2, 3)) self.os.close(fd2) self.os.close(fd1) def test_writing_behind_end_of_file(self): # Regression test for #273 file_path = self.make_path('baz') fd1 = self.os.open(file_path, os.O_CREAT) fd2 = self.os.open(file_path, os.O_RDWR) self.os.write(fd2, b'm') fd3 = self.os.open(file_path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC) self.assertEqual(b'', self.os.read(fd2, 1)) self.os.write(fd2, b'm') self.assertEqual(b'\x00m', self.os.read(fd1, 2)) self.os.close(fd1) self.os.close(fd2) self.os.close(fd3) def test_devnull_posix(self): self.check_posix_only() self.assertTrue(self.os.path.exists(self.os.devnull)) def test_devnull_windows(self): self.check_windows_only() self.assertFalse(self.os.path.exists(self.os.devnull)) def test_write_devnull(self): fd = self.os.open(self.os.devnull, os.O_RDWR) self.assertEqual(4, self.os.write(fd, b'test')) self.assertEqual(b'', self.os.read(fd, 4)) self.os.close(fd) fd = self.os.open(self.os.devnull, os.O_RDONLY) self.assertEqual(b'', self.os.read(fd, 4)) self.os.close(fd) class RealOsModuleLowLevelFileOpTest(FakeOsModuleLowLevelFileOpTest): def use_real_fs(self): return True class FakeOsModuleWalkTest(FakeOsModuleTestBase): def assertWalkResults(self, expected, top, topdown=True, followlinks=False): # as the result of walk is unsorted, we have to check against # sorted results result = [step for step in self.os.walk( top, topdown=topdown, followlinks=followlinks)] result = sorted(result, key=lambda lst: lst[0]) expected = sorted(expected, key=lambda lst: lst[0]) self.assertEqual(len(expected), len(result)) for entry, expected_entry in zip(result, expected): self.assertEqual(expected_entry[0], entry[0]) self.assertEqual(expected_entry[1], sorted(entry[1])) self.assertEqual(expected_entry[2], sorted(entry[2])) def ResetErrno(self): """Reset the last seen errno.""" self.last_errno = False def StoreErrno(self, os_error): """Store the last errno we saw.""" self.last_errno = os_error.errno def GetErrno(self): """Return the last errno we saw.""" return self.last_errno def test_walk_top_down(self): """Walk down ordering is correct.""" base_dir = self.make_path('foo') self.create_file(self.os.path.join(base_dir, '1.txt')) self.create_file(self.os.path.join(base_dir, 'bar1', '2.txt')) self.create_file(self.os.path.join(base_dir, 'bar1', 'baz', '3.txt')) self.create_file(self.os.path.join(base_dir, 'bar2', '4.txt')) expected = [ (base_dir, ['bar1', 'bar2'], ['1.txt']), (self.os.path.join(base_dir, 'bar1'), ['baz'], ['2.txt']), (self.os.path.join(base_dir, 'bar1', 'baz'), [], ['3.txt']), (self.os.path.join(base_dir, 'bar2'), [], ['4.txt']), ] self.assertWalkResults(expected, base_dir) def test_walk_bottom_up(self): """Walk up ordering is correct.""" base_dir = self.make_path('foo') self.create_file(self.os.path.join(base_dir, 'bar1', 'baz', '1.txt')) self.create_file(self.os.path.join(base_dir, 'bar1', '2.txt')) self.create_file(self.os.path.join(base_dir, 'bar2', '3.txt')) self.create_file(self.os.path.join(base_dir, '4.txt')) expected = [ (self.os.path.join(base_dir, 'bar1', 'baz'), [], ['1.txt']), (self.os.path.join(base_dir, 'bar1'), ['baz'], ['2.txt']), (self.os.path.join(base_dir, 'bar2'), [], ['3.txt']), (base_dir, ['bar1', 'bar2'], ['4.txt']), ] self.assertWalkResults(expected, self.make_path('foo'), topdown=False) def test_walk_raises_if_non_existent(self): """Raises an exception when attempting to walk non-existent directory.""" directory = self.make_path('foo', 'bar') self.assertEqual(False, self.os.path.exists(directory)) generator = self.os.walk(directory) self.assertRaises(StopIteration, next, generator) def test_walk_raises_if_not_directory(self): """Raises an exception when attempting to walk a non-directory.""" filename = self.make_path('foo', 'bar') self.create_file(filename) generator = self.os.walk(filename) self.assertRaises(StopIteration, next, generator) def test_walk_calls_on_error_if_non_existent(self): """Calls onerror with correct errno when walking non-existent directory.""" self.ResetErrno() directory = self.make_path('foo', 'bar') self.assertEqual(False, self.os.path.exists(directory)) # Calling os.walk on a non-existent directory should trigger # a call to the onerror method. # We do not actually care what, if anything, is returned. for _ in self.os.walk(directory, onerror=self.StoreErrno): pass self.assertTrue(self.GetErrno() in (errno.ENOTDIR, errno.ENOENT)) def test_walk_calls_on_error_if_not_directory(self): """Calls onerror with correct errno when walking non-directory.""" self.ResetErrno() filename = self.make_path('foo' 'bar') self.create_file(filename) self.assertEqual(True, self.os.path.exists(filename)) # Calling `os.walk` on a file should trigger a call to the # `onerror` method. # We do not actually care what, if anything, is returned. for _ in self.os.walk(filename, onerror=self.StoreErrno): pass self.assertTrue(self.GetErrno() in (self.not_dir_error(), errno.EACCES)) def test_walk_skips_removed_directories(self): """Caller can modify list of directories to visit while walking.""" root = self.make_path('foo') visit = 'visit' no_visit = 'no_visit' self.create_file(self.os.path.join(root, 'bar')) self.create_file(self.os.path.join(root, visit, '1.txt')) self.create_file(self.os.path.join(root, visit, '2.txt')) self.create_file(self.os.path.join(root, no_visit, '3.txt')) self.create_file(self.os.path.join(root, no_visit, '4.txt')) generator = self.os.walk(self.make_path('foo')) root_contents = next(generator) root_contents[1].remove(no_visit) visited_visit_directory = False for root, _dirs, _files in iter(generator): self.assertEqual(False, root.endswith(self.os.path.sep + no_visit)) if root.endswith(self.os.path.sep + visit): visited_visit_directory = True self.assertEqual(True, visited_visit_directory) def test_walk_followsymlink_disabled(self): self.check_posix_only() base_dir = self.make_path('foo') link_dir = self.make_path('linked') self.create_file(self.os.path.join(link_dir, 'subfile')) self.create_file(self.os.path.join(base_dir, 'bar', 'baz')) self.create_file(self.os.path.join(base_dir, 'bar', 'xyzzy', 'plugh')) self.create_symlink( self.os.path.join(base_dir, 'created_link'), link_dir) expected = [ (base_dir, ['bar', 'created_link'], []), (self.os.path.join(base_dir, 'bar'), ['xyzzy'], ['baz']), (self.os.path.join(base_dir, 'bar', 'xyzzy'), [], ['plugh']), ] self.assertWalkResults(expected, base_dir, followlinks=False) expected = [(self.os.path.join(base_dir, 'created_link'), [], ['subfile'])] self.assertWalkResults(expected, self.os.path.join(base_dir, 'created_link'), followlinks=False) def test_walk_followsymlink_enabled(self): self.check_posix_only() base_dir = self.make_path('foo') link_dir = self.make_path('linked') self.create_file(self.os.path.join(link_dir, 'subfile')) self.create_file(self.os.path.join(base_dir, 'bar', 'baz')) self.create_file(self.os.path.join(base_dir, 'bar', 'xyzzy', 'plugh')) self.create_symlink(self.os.path.join(base_dir, 'created_link'), self.os.path.join(link_dir)) expected = [ (base_dir, ['bar', 'created_link'], []), (self.os.path.join(base_dir, 'bar'), ['xyzzy'], ['baz']), (self.os.path.join(base_dir, 'bar', 'xyzzy'), [], ['plugh']), (self.os.path.join(base_dir, 'created_link'), [], ['subfile']), ] self.assertWalkResults(expected, base_dir, followlinks=True) expected = [(self.os.path.join(base_dir, 'created_link'), [], ['subfile'])] self.assertWalkResults(expected, self.os.path.join(base_dir, 'created_link'), followlinks=True) class RealOsModuleWalkTest(FakeOsModuleWalkTest): def use_real_fs(self): return True @unittest.skipIf(sys.version_info < (3, 3), 'dir_fd argument was introduced in Python 3.3') class FakeOsModuleDirFdTest(FakeOsModuleTestBase): def setUp(self): super(FakeOsModuleDirFdTest, self).setUp() self.os.supports_dir_fd = set() self.filesystem.is_windows_fs = False self.filesystem.create_dir('/foo/bar') self.dir_fd = self.os.open('/foo', os.O_RDONLY) self.filesystem.create_file('/foo/baz') def test_access(self): self.assertRaises( NotImplementedError, self.os.access, 'baz', self.os.F_OK, dir_fd=self.dir_fd) self.os.supports_dir_fd.add(os.access) self.assertTrue( self.os.access('baz', self.os.F_OK, dir_fd=self.dir_fd)) def test_chmod(self): self.assertRaises( NotImplementedError, self.os.chmod, 'baz', 0o6543, dir_fd=self.dir_fd) self.os.supports_dir_fd.add(os.chmod) self.os.chmod('baz', 0o6543, dir_fd=self.dir_fd) st = self.os.stat('/foo/baz') self.assert_mode_equal(0o6543, st.st_mode) @unittest.skipIf(not hasattr(os, 'chown'), 'chown not on all platforms available') def test_chown(self): self.assertRaises( NotImplementedError, self.os.chown, 'baz', 100, 101, dir_fd=self.dir_fd) self.os.supports_dir_fd.add(os.chown) self.os.chown('baz', 100, 101, dir_fd=self.dir_fd) st = self.os.stat('/foo/baz') self.assertEqual(st[stat.ST_UID], 100) self.assertEqual(st[stat.ST_GID], 101) def test_link(self): self.assertRaises( NotImplementedError, self.os.link, 'baz', '/bat', dir_fd=self.dir_fd) self.os.supports_dir_fd.add(os.link) self.os.link('baz', '/bat', dir_fd=self.dir_fd) self.assertTrue(self.os.path.exists('/bat')) def test_symlink(self): self.assertRaises( NotImplementedError, self.os.symlink, 'baz', '/bat', dir_fd=self.dir_fd) self.os.supports_dir_fd.add(os.symlink) self.os.symlink('baz', '/bat', dir_fd=self.dir_fd) self.assertTrue(self.os.path.exists('/bat')) def test_readlink(self): self.filesystem.create_symlink('/meyer/lemon/pie', '/foo/baz') self.filesystem.create_symlink('/geo/metro', '/meyer') self.assertRaises( NotImplementedError, self.os.readlink, '/geo/metro/lemon/pie', dir_fd=self.dir_fd) self.os.supports_dir_fd.add(os.readlink) self.assertEqual('/foo/baz', self.os.readlink( '/geo/metro/lemon/pie', dir_fd=self.dir_fd)) def test_stat(self): self.assertRaises( NotImplementedError, self.os.stat, 'baz', dir_fd=self.dir_fd) self.os.supports_dir_fd.add(os.stat) st = self.os.stat('baz', dir_fd=self.dir_fd) self.assertEqual(st.st_mode, 0o100666) def test_lstat(self): self.assertRaises( NotImplementedError, self.os.lstat, 'baz', dir_fd=self.dir_fd) self.os.supports_dir_fd.add(os.lstat) st = self.os.lstat('baz', dir_fd=self.dir_fd) self.assertEqual(st.st_mode, 0o100666) def test_mkdir(self): self.assertRaises( NotImplementedError, self.os.mkdir, 'newdir', dir_fd=self.dir_fd) self.os.supports_dir_fd.add(os.mkdir) self.os.mkdir('newdir', dir_fd=self.dir_fd) self.assertTrue(self.os.path.exists('/foo/newdir')) def test_rmdir(self): self.assertRaises( NotImplementedError, self.os.rmdir, 'bar', dir_fd=self.dir_fd) self.os.supports_dir_fd.add(os.rmdir) self.os.rmdir('bar', dir_fd=self.dir_fd) self.assertFalse(self.os.path.exists('/foo/bar')) @unittest.skipIf(not hasattr(os, 'mknod'), 'mknod not on all platforms available') def test_mknod(self): self.assertRaises( NotImplementedError, self.os.mknod, 'newdir', dir_fd=self.dir_fd) self.os.supports_dir_fd.add(os.mknod) self.os.mknod('newdir', dir_fd=self.dir_fd) self.assertTrue(self.os.path.exists('/foo/newdir')) def test_rename(self): self.assertRaises( NotImplementedError, self.os.rename, 'baz', '/foo/batz', dir_fd=self.dir_fd) self.os.supports_dir_fd.add(os.rename) self.os.rename('bar', '/foo/batz', dir_fd=self.dir_fd) self.assertTrue(self.os.path.exists('/foo/batz')) def test_remove(self): self.assertRaises( NotImplementedError, self.os.remove, 'baz', dir_fd=self.dir_fd) self.os.supports_dir_fd.add(os.remove) self.os.remove('baz', dir_fd=self.dir_fd) self.assertFalse(self.os.path.exists('/foo/baz')) def test_unlink(self): self.assertRaises( NotImplementedError, self.os.unlink, 'baz', dir_fd=self.dir_fd) self.os.supports_dir_fd.add(os.unlink) self.os.unlink('baz', dir_fd=self.dir_fd) self.assertFalse(self.os.path.exists('/foo/baz')) def test_utime(self): self.assertRaises( NotImplementedError, self.os.utime, 'baz', (1, 2), dir_fd=self.dir_fd) self.os.supports_dir_fd.add(os.utime) self.os.utime('baz', (1, 2), dir_fd=self.dir_fd) st = self.os.stat('/foo/baz') self.assertEqual(1, st.st_atime) self.assertEqual(2, st.st_mtime) def test_open(self): self.assertRaises( NotImplementedError, self.os.open, 'baz', os.O_RDONLY, dir_fd=self.dir_fd) self.os.supports_dir_fd.add(os.open) fd = self.os.open('baz', os.O_RDONLY, dir_fd=self.dir_fd) self.assertLess(0, fd) class StatPropagationTest(TestCase): def setUp(self): self.filesystem = fake_filesystem.FakeFilesystem(path_separator='/') self.os = fake_filesystem.FakeOsModule(self.filesystem) self.open = fake_filesystem.FakeFileOpen(self.filesystem) def test_file_size_updated_via_close(self): """test that file size gets updated via close().""" file_dir = 'xyzzy' file_path = 'xyzzy/close' content = 'This is a test.' self.os.mkdir(file_dir) fh = self.open(file_path, 'w') self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE]) self.assertEqual('', self.filesystem.get_object(file_path).contents) fh.write(content) self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE]) self.assertEqual('', self.filesystem.get_object(file_path).contents) fh.close() self.assertEqual(len(content), self.os.stat(file_path)[stat.ST_SIZE]) self.assertEqual(content, self.filesystem.get_object(file_path).contents) def test_file_size_not_reset_after_close(self): file_dir = 'xyzzy' file_path = 'xyzzy/close' self.os.mkdir(file_dir) size = 1234 # The file has size, but no content. When the file is opened for # reading, its size should be preserved. self.filesystem.create_file(file_path, st_size=size) fh = self.open(file_path, 'r') fh.close() self.assertEqual(size, self.open(file_path, 'r').size()) def test_file_size_after_write(self): file_path = 'test_file' original_content = 'abcdef' original_size = len(original_content) self.filesystem.create_file(file_path, contents=original_content) added_content = 'foo bar' expected_size = original_size + len(added_content) fh = self.open(file_path, 'a') fh.write(added_content) self.assertEqual(original_size, fh.size()) fh.close() self.assertEqual(expected_size, self.open(file_path, 'r').size()) def test_large_file_size_after_write(self): file_path = 'test_file' original_content = 'abcdef' original_size = len(original_content) self.filesystem.create_file(file_path, st_size=original_size) added_content = 'foo bar' fh = self.open(file_path, 'a') self.assertRaises(fake_filesystem.FakeLargeFileIoException, lambda: fh.write(added_content)) def test_file_size_updated_via_flush(self): """test that file size gets updated via flush().""" file_dir = 'xyzzy' file_name = 'flush' file_path = self.os.path.join(file_dir, file_name) content = 'This might be a test.' self.os.mkdir(file_dir) fh = self.open(file_path, 'w') self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE]) self.assertEqual('', self.filesystem.get_object(file_path).contents) fh.write(content) self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE]) self.assertEqual('', self.filesystem.get_object(file_path).contents) fh.flush() self.assertEqual(len(content), self.os.stat(file_path)[stat.ST_SIZE]) self.assertEqual(content, self.filesystem.get_object(file_path).contents) fh.close() self.assertEqual(len(content), self.os.stat(file_path)[stat.ST_SIZE]) self.assertEqual(content, self.filesystem.get_object(file_path).contents) def test_file_size_truncation(self): """test that file size gets updated via open().""" file_dir = 'xyzzy' file_path = 'xyzzy/truncation' content = 'AAA content.' # pre-create file with content self.os.mkdir(file_dir) fh = self.open(file_path, 'w') fh.write(content) fh.close() self.assertEqual(len(content), self.os.stat(file_path)[stat.ST_SIZE]) self.assertEqual(content, self.filesystem.get_object(file_path).contents) # test file truncation fh = self.open(file_path, 'w') self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE]) self.assertEqual('', self.filesystem.get_object(file_path).contents) fh.close() @unittest.skipIf(not use_scandir, 'only run if scandir is available') class FakeScandirTest(FakeOsModuleTestBase): def setUp(self): super(FakeScandirTest, self).setUp() self.supports_symlinks = (not self.is_windows or not self.use_real_fs() and not self.is_python2) if use_scandir_package: if self.use_real_fs(): from scandir import scandir else: import pyfakefs.fake_scandir def fake_scan_dir(p): return pyfakefs.fake_scandir.scandir(self.filesystem, p) scandir = fake_scan_dir else: scandir = self.os.scandir self.scandir = scandir self.directory = self.make_path('xyzzy', 'plugh') link_dir = self.make_path('linked', 'plugh') self.linked_file_path = self.os.path.join(link_dir, 'file') self.linked_dir_path = self.os.path.join(link_dir, 'dir') self.create_dir(self.linked_dir_path) self.create_file(self.linked_file_path, contents=b'a' * 10) self.dir_path = self.os.path.join(self.directory, 'dir') self.create_dir(self.dir_path) self.file_path = self.os.path.join(self.directory, 'file') self.create_file(self.file_path, contents=b'b' * 50) self.file_link_path = self.os.path.join(self.directory, 'link_file') if self.supports_symlinks: self.create_symlink(self.file_link_path, self.linked_file_path) self.dir_link_path = self.os.path.join(self.directory, 'link_dir') self.create_symlink(self.dir_link_path, self.linked_dir_path) self.dir_entries = [entry for entry in self.scandir(self.directory)] self.dir_entries = sorted(self.dir_entries, key=lambda entry: entry.name) def test_paths(self): sorted_names = ['dir', 'file'] if self.supports_symlinks: sorted_names.extend(['link_dir', 'link_file']) self.assertEqual(len(sorted_names), len(self.dir_entries)) self.assertEqual(sorted_names, [entry.name for entry in self.dir_entries]) self.skip_real_fs() # this one does not work in the real fs - will wait for # final 3.7 release to check into this self.assertEqual(self.dir_path, self.dir_entries[0].path) def test_isfile(self): self.assertFalse(self.dir_entries[0].is_file()) self.assertTrue(self.dir_entries[1].is_file()) if self.supports_symlinks: self.assertFalse(self.dir_entries[2].is_file()) self.assertFalse( self.dir_entries[2].is_file(follow_symlinks=False)) self.assertTrue(self.dir_entries[3].is_file()) self.assertFalse( self.dir_entries[3].is_file(follow_symlinks=False)) def test_isdir(self): self.assertTrue(self.dir_entries[0].is_dir()) self.assertFalse(self.dir_entries[1].is_dir()) if self.supports_symlinks: self.assertTrue(self.dir_entries[2].is_dir()) self.assertFalse(self.dir_entries[2].is_dir(follow_symlinks=False)) self.assertFalse(self.dir_entries[3].is_dir()) self.assertFalse(self.dir_entries[3].is_dir(follow_symlinks=False)) def test_is_link(self): if self.supports_symlinks: self.assertFalse(self.dir_entries[0].is_symlink()) self.assertFalse(self.dir_entries[1].is_symlink()) self.assertTrue(self.dir_entries[2].is_symlink()) self.assertTrue(self.dir_entries[3].is_symlink()) def test_path_links_not_resolved(self): # regression test for #350 self.skip_if_symlink_not_supported() dir_path = self.make_path('A', 'B', 'C') self.os.makedirs(self.os.path.join(dir_path, 'D')) link_path = self.make_path('A', 'C') self.os.symlink(dir_path, link_path) self.assertEqual([self.os.path.join(link_path, 'D')], [f.path for f in self.scandir(link_path)]) def test_inode(self): if use_scandir and self.use_real_fs(): if self.is_windows: self.skipTest( 'inode seems not to work in scandir module under Windows') if os.path.exists('/.dockerenv'): self.skipTest( 'inode seems not to work in a Docker container') self.assertEqual(self.os.stat(self.dir_path).st_ino, self.dir_entries[0].inode()) self.assertEqual(self.os.stat(self.file_path).st_ino, self.dir_entries[1].inode()) if self.supports_symlinks: self.assertEqual(self.os.lstat(self.dir_link_path).st_ino, self.dir_entries[2].inode()) self.assertEqual(self.os.lstat(self.file_link_path).st_ino, self.dir_entries[3].inode()) def check_stat(self, expected_size): self.assertEqual(50, self.dir_entries[1].stat().st_size) self.assertEqual( self.os.stat(self.dir_path).st_ctime, self.dir_entries[0].stat().st_ctime) if self.supports_symlinks: self.assertEqual(10, self.dir_entries[3].stat().st_size) self.assertEqual(expected_size, self.dir_entries[3].stat( follow_symlinks=False).st_size) self.assertEqual( self.os.stat(self.linked_dir_path).st_mtime, self.dir_entries[2].stat().st_mtime) @unittest.skipIf(TestCase.is_windows, 'POSIX specific behavior') def test_stat_posix(self): self.check_stat(len(self.linked_file_path)) @unittest.skipIf(not TestCase.is_windows, 'Windows specific behavior') def test_stat_windows(self): self.check_stat(0) def test_index_access_to_stat_times_returns_int(self): self.assertEqual(self.os.stat(self.dir_path)[stat.ST_CTIME], int(self.dir_entries[0].stat().st_ctime)) if self.supports_symlinks: self.assertEqual(self.os.stat(self.linked_dir_path)[stat.ST_MTIME], int(self.dir_entries[2].stat().st_mtime)) def test_stat_ino_dev(self): if self.supports_symlinks: file_stat = self.os.stat(self.linked_file_path) self.assertEqual(file_stat.st_ino, self.dir_entries[3].stat().st_ino) self.assertEqual(file_stat.st_dev, self.dir_entries[3].stat().st_dev) class RealScandirTest(FakeScandirTest): def use_real_fs(self): return True @unittest.skipIf(sys.version_info < (3, 7) or TestCase.is_windows, 'dir_fd support for os.scandir was introduced in Python 3.7') class FakeScandirFdTest(FakeScandirTest): def setUp(self): super(FakeScandirFdTest, self).setUp() self.dir_fd = self.os.open(self.directory, os.O_RDONLY) self.dir_entries = [entry for entry in self.scandir(self.dir_fd)] self.dir_entries = sorted(self.dir_entries, key=lambda entry: entry.name) def tearDown(self): self.os.close(self.dir_fd) super(FakeScandirFdTest, self).tearDown() class RealScandirFdTest(FakeScandirFdTest): def use_real_fs(self): return True @unittest.skipIf(TestCase.is_python2, reason='Xattr only supported in Linux/Python 3') class FakeExtendedAttributeTest(FakeOsModuleTestBase): def setUp(self): super(FakeExtendedAttributeTest, self).setUp() self.check_linux_only() self.dir_path = self.make_path('foo') self.file_path = self.os.path.join(self.dir_path, 'bar') self.create_file(self.file_path) def test_empty_xattr(self): self.assertEqual([], self.os.listxattr(self.dir_path)) self.assertEqual([], self.os.listxattr(self.file_path)) def test_setxattr(self): self.assertRaises(TypeError, self.os.setxattr, self.file_path, 'test', 'value') self.assert_raises_os_error(errno.EEXIST, self.os.setxattr, self.file_path, 'test', b'value', self.os.XATTR_REPLACE) self.os.setxattr(self.file_path, 'test', b'value') self.assertEqual(b'value', self.os.getxattr(self.file_path, 'test')) self.assert_raises_os_error(errno.ENODATA, self.os.setxattr, self.file_path, 'test', b'value', self.os.XATTR_CREATE) def test_removeattr(self): self.os.removexattr(self.file_path, 'test') self.assertEqual([], self.os.listxattr(self.file_path)) self.os.setxattr(self.file_path, b'test', b'value') self.assertEqual(['test'], self.os.listxattr(self.file_path)) self.assertEqual(b'value', self.os.getxattr(self.file_path, 'test')) self.os.removexattr(self.file_path, 'test') self.assertEqual([], self.os.listxattr(self.file_path)) self.assertIsNone(self.os.getxattr(self.file_path, 'test')) def test_default_path(self): self.os.chdir(self.dir_path) self.os.setxattr(self.dir_path, b'test', b'value') self.assertEqual(['test'], self.os.listxattr()) self.assertEqual(b'value', self.os.getxattr(self.dir_path, 'test'))