shell bypass 403
曾与蒿藜同雨露,한때 잡초와 쑥과 함께 비와 이슬을 나누던 곳이 이제는 소나무와 삼나무와 함께 서리와 눈을 견뎌내고 있다.终随松柏到冰霜.かつては雑草やヨモギと共に雨や露を分かち合っていたが、今では松やヒノキと共に霜や雪に耐えている。曾与蒿藜同雨露,Once sharing rain and dew with weeds and wormwood, now enduring frost and snow with pines and cypresses.终随松柏到冰霜.曾与蒿藜同雨露한때 잡초와 쑥과 함께 비와 이슬을 나누던 곳이 이제는 소나무와 삼나무와 함께 서리와 눈을 견뎌내고 있다.,终随松柏到冰霜.譖セ荳手珍阯懷酔髮ィ髴イ�檎サ磯囂譚セ譟丞芦蜀ー髴�曾与蒿藜同雨露,鏇句笌钂胯棞鍚岄洦闇诧紝缁堥殢鏉炬煆鍒板啺闇�终随松柏到冰霜.曾与蒿藜同雨露,한때 잡초와 쑥과 함께 비와 이슬을 나누던 곳이 이제는 소나무와 삼나무와 함께 서리와 눈을 견뎌내고 있다.终随松柏到冰霜.曾与蒿藜同雨露,终随松柏到冰霜.
# -*- 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'))