Permalink
Browse files

Added methods to access real files

- allow to add really existing files and directory trees to the fake
file system, with the contents read on demand
- see #170
  • Loading branch information...
mrbean-bremen committed Apr 1, 2017
1 parent f6fc906 commit 143438cfdb07e1d4893b706fcb24bdb43fb1fa63
Showing with 314 additions and 30 deletions.
  1. +5 −1 CHANGES.md
  2. +6 −1 example.py
  3. +12 −1 example_test.py
  4. +132 −1 fake_filesystem_test.py
  5. +23 −1 fake_filesystem_unittest_test.py
  6. +134 −24 pyfakefs/fake_filesystem.py
  7. +2 −1 pyfakefs/fake_filesystem_unittest.py
View
@@ -4,7 +4,11 @@ The release versions are PyPi releases.
## Version 3.2 (as yet unreleased)
#### New Features
* Added the CHANGES.md release notes to the release manifest
* Added new methods to `fake_filesystem.FakeFilesystem` that make real files
and directories appear within the fake file system:
`add_real_file()`, `add_real_directory()` and `add_real_paths()`.
File contents are read from the real file system only when needed.
* Added the CHANGES.md release notes to the release manifest
#### Fixes
* `pathlib.glob()` incorrectly handled case under MacOS (#167)
View
@@ -132,5 +132,10 @@ def rm_tree(path):
shutil.rmtree(path)
def scandir(path):
"""Returns a list of directory entries for the given path."""
"""Return a list of directory entries for the given path."""
return list(os.scandir(path))
def file_contents(path):
"""Return the contents of the given path as byte array."""
with open(path, 'rb') as f:
return f.read()
View
@@ -30,6 +30,8 @@
import os
import sys
from pyfakefs.fake_filesystem_unittest import REAL_OPEN
if sys.version_info < (2, 7):
import unittest2 as unittest
else:
@@ -135,13 +137,22 @@ def test_scandir(self):
self.fs.CreateFile('/linktest/linked')
self.fs.CreateLink('/test/linked_file', '/linktest/linked')
entries = sorted(os.scandir('/test'), key=lambda e: e.name)
entries = sorted(example.scandir('/test'), key=lambda e: e.name)
self.assertEqual(3, len(entries))
self.assertEqual('linked_file', entries[1].name)
self.assertTrue(entries[0].is_dir())
self.assertTrue(entries[1].is_symlink())
self.assertTrue(entries[2].is_file())
def test_real_file_access(self):
"""Test `example.file_contents()` for a real file after adding it using `add_real_file()`."""
real_file = __file__
with REAL_OPEN(real_file, 'rb') as f:
real_contents = f.read()
self.assertRaises(IOError, example.file_contents, real_file)
self.fs.add_real_file(real_file)
self.assertEqual(example.file_contents(real_file), real_contents)
if __name__ == "__main__":
unittest.main()
View
@@ -4186,6 +4186,7 @@ def testDiskUsageOnFileCreation(self):
total_size = 100
self.filesystem.AddMountPoint('mount', total_size)
def create_too_large_file():
with fake_open('!mount!file', 'w') as dest:
dest.write('a' * (total_size + 1))
@@ -4199,7 +4200,6 @@ def create_too_large_file():
self.assertEqual(total_size, self.filesystem.GetDiskUsage('!mount').used)
def testFileSystemSizeAfterLargeFileCreation(self):
filesystem = fake_filesystem.FakeFilesystem(path_separator='!',
total_size=1024 * 1024 * 1024 * 100)
@@ -4444,5 +4444,136 @@ def testThatUncPathsAreAutoMounted(self):
self.assertEqual(5, self.filesystem.GetObject('!!foo!bar!bip!bop').st_dev)
class RealFileSystemAccessTest(TestCase):
def setUp(self):
# use the real path separator to work with the real file system
self.filesystem = fake_filesystem.FakeFilesystem()
self.fake_open = fake_filesystem.FakeFileOpen(self.filesystem)
def testAddNonExistingRealFileRaises(self):
nonexisting_path = os.path.join('nonexisting', 'test.txt')
self.assertRaises(OSError, self.filesystem.add_real_file, nonexisting_path)
self.assertFalse(self.filesystem.Exists(nonexisting_path))
def testAddNonExistingRealDirectoryRaises(self):
nonexisting_path = '/nonexisting'
self.assertRaisesIOError(errno.ENOENT, self.filesystem.add_real_directory, nonexisting_path)
self.assertFalse(self.filesystem.Exists(nonexisting_path))
def testExistingFakeFileRaises(self):
real_file_path = __file__
self.filesystem.CreateFile(real_file_path)
self.assertRaisesIOError(errno.EEXIST, self.filesystem.add_real_file, real_file_path)
def testExistingFakeDirectoryRaises(self):
real_dir_path = os.path.dirname(__file__)
self.filesystem.CreateDirectory(real_dir_path)
self.assertRaisesOSError(errno.EEXIST, self.filesystem.add_real_directory, real_dir_path)
def checkFakeFileStat(self, fake_file, real_file_path):
self.assertTrue(self.filesystem.Exists(real_file_path))
real_stat = os.stat(real_file_path)
self.assertIsNone(fake_file._byte_contents)
self.assertEqual(fake_file.st_size, real_stat.st_size)
self.assertEqual(fake_file.st_ctime, real_stat.st_ctime)
self.assertEqual(fake_file.st_atime, real_stat.st_atime)
self.assertEqual(fake_file.st_mtime, real_stat.st_mtime)
self.assertEqual(fake_file.st_uid, real_stat.st_uid)
self.assertEqual(fake_file.st_gid, real_stat.st_gid)
def checkReadOnlyFile(self, fake_file, real_file_path):
with open(real_file_path, 'rb') as f:
real_contents = f.read()
self.assertEqual(fake_file.byte_contents, real_contents)
self.assertRaisesIOError(errno.EACCES, self.fake_open, real_file_path, 'w')
def checkWritableFile(self, fake_file, real_file_path):
with open(real_file_path, 'rb') as f:
real_contents = f.read()
self.assertEqual(fake_file.byte_contents, real_contents)
with self.fake_open(real_file_path, 'wb') as f:
f.write(b'test')
with open(real_file_path, 'rb') as f:
real_contents1 = f.read()
self.assertEqual(real_contents1, real_contents)
with self.fake_open(real_file_path, 'rb') as f:
fake_contents = f.read()
self.assertEqual(fake_contents, b'test')
def testAddExistingRealFileReadOnly(self):
real_file_path = __file__
fake_file = self.filesystem.add_real_file(real_file_path)
self.checkFakeFileStat(fake_file, real_file_path)
self.assertEqual(fake_file.st_mode & 0o333, 0)
self.checkReadOnlyFile(fake_file, real_file_path)
def testAddExistingRealFileReadWrite(self):
real_file_path = os.path.realpath(__file__)
fake_file = self.filesystem.add_real_file(real_file_path, read_only=False)
self.checkFakeFileStat(fake_file, real_file_path)
self.assertEqual(fake_file.st_mode, os.stat(real_file_path).st_mode)
self.checkWritableFile(fake_file, real_file_path)
def testAddExistingRealDirectoryReadOnly(self):
real_dir_path = os.path.join(os.path.dirname(__file__), 'pyfakefs')
fake_dir = self.filesystem.add_real_directory(real_dir_path)
self.assertTrue(self.filesystem.Exists(real_dir_path))
self.assertTrue(self.filesystem.Exists(os.path.join(real_dir_path, 'fake_filesystem.py')))
self.assertTrue(self.filesystem.Exists(os.path.join(real_dir_path, 'fake_pathlib.py')))
file_path = os.path.join(real_dir_path, 'fake_tempfile.py')
fake_file = self.filesystem.ResolveObject(file_path)
self.checkFakeFileStat(fake_file, file_path)
self.checkReadOnlyFile(fake_file, file_path)
def testAddExistingRealDirectoryTree(self):
real_dir_path = os.path.dirname(__file__)
self.filesystem.add_real_directory(real_dir_path)
self.assertTrue(self.filesystem.Exists(os.path.join(real_dir_path, 'fake_filesystem_test.py')))
self.assertTrue(self.filesystem.Exists(os.path.join(real_dir_path, 'pyfakefs', 'fake_filesystem.py')))
self.assertTrue(self.filesystem.Exists(os.path.join(real_dir_path, 'pyfakefs', '__init__.py')))
def testAddExistingRealDirectoryReadWrite(self):
real_dir_path = os.path.join(os.path.dirname(__file__), 'pyfakefs')
self.filesystem.add_real_directory(real_dir_path, read_only=False)
self.assertTrue(self.filesystem.Exists(real_dir_path))
self.assertTrue(self.filesystem.Exists(os.path.join(real_dir_path, 'fake_filesystem.py')))
self.assertTrue(self.filesystem.Exists(os.path.join(real_dir_path, 'fake_pathlib.py')))
file_path = os.path.join(real_dir_path, 'pytest_plugin.py')
fake_file = self.filesystem.ResolveObject(file_path)
self.checkFakeFileStat(fake_file, file_path)
self.checkWritableFile(fake_file, file_path)
def testAddExistingRealPathsReadOnly(self):
real_file_path = os.path.realpath(__file__)
real_dir_path = os.path.join(os.path.dirname(__file__), 'pyfakefs')
self.filesystem.add_real_paths([real_file_path, real_dir_path])
fake_file = self.filesystem.ResolveObject(real_file_path)
self.checkFakeFileStat(fake_file, real_file_path)
self.checkReadOnlyFile(fake_file, real_file_path)
real_file_path = os.path.join(real_dir_path, 'fake_filesystem_shutil.py')
fake_file = self.filesystem.ResolveObject(real_file_path)
self.checkFakeFileStat(fake_file, real_file_path)
self.checkReadOnlyFile(fake_file, real_file_path)
def testAddExistingRealPathsReadWrite(self):
real_file_path = os.path.realpath(__file__)
real_dir_path = os.path.join(os.path.dirname(__file__), 'pyfakefs')
self.filesystem.add_real_paths([real_file_path, real_dir_path], read_only=False)
fake_file = self.filesystem.ResolveObject(real_file_path)
self.checkFakeFileStat(fake_file, real_file_path)
self.checkWritableFile(fake_file, real_file_path)
real_file_path = os.path.join(real_dir_path, 'fake_filesystem_glob.py')
fake_file = self.filesystem.ResolveObject(real_file_path)
self.checkFakeFileStat(fake_file, real_file_path)
self.checkWritableFile(fake_file, real_file_path)
if __name__ == '__main__':
unittest.main()
@@ -190,7 +190,7 @@ def test_own_path_module(self):
@unittest.skipIf(sys.version_info < (2, 7), "No byte strings in Python 2.6")
class TestCopyRealFile(TestPyfakefsUnittestBase):
class TestCopyOrAddRealFile(TestPyfakefsUnittestBase):
"""Tests the `fake_filesystem_unittest.TestCase.copyRealFile()` method."""
with open(__file__) as f:
real_string_contents = f.read()
@@ -235,6 +235,28 @@ def testCopyRealFileNoDestination(self):
self.copyRealFile(real_file_path)
self.assertTrue(self.fs.Exists(real_file_path))
def testAddRealFile(self):
'''Add a real file to the fake file system to be read on demand'''
# this tests only the basic functionality inside a unit test, more thorough tests
# are done in fake_filesystem_test.RealFileSystemAccessTest
real_file_path = __file__
fake_file = self.fs.add_real_file(real_file_path)
self.assertTrue(self.fs.Exists(real_file_path))
self.assertIsNone(fake_file._byte_contents)
self.assertEqual(self.real_byte_contents, fake_file.byte_contents)
def testAddRealDirectory(self):
'''Add a real directory and the contained files to the fake file system to be read on demand'''
# this tests only the basic functionality inside a unit test, more thorough tests
# are done in fake_filesystem_test.RealFileSystemAccessTest
# Note: this test fails (add_real_directory raises) if 'genericpath' is not added to SKIPNAMES
real_dir_path = os.path.join(os.path.dirname(__file__), 'pyfakefs')
self.fs.add_real_directory(real_dir_path)
self.assertTrue(self.fs.Exists(real_dir_path))
self.assertTrue(self.fs.Exists(os.path.join(real_dir_path, 'fake_filesystem.py')))
if __name__ == "__main__":
unittest.main()
Oops, something went wrong.

0 comments on commit 143438c

Please sign in to comment.