Skip to content

Commit

Permalink
Added xtime_ns in stat result
Browse files Browse the repository at this point in the history
- added fake stat_result to make this possible
- fixes pytest-dev#196
  • Loading branch information
mrbean-bremen committed Jun 10, 2017
1 parent 2e51917 commit 6e2c752
Show file tree
Hide file tree
Showing 5 changed files with 292 additions and 140 deletions.
4 changes: 3 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ The release versions are PyPi releases.

#### New Features
* Added fake `os.path.samefile` implementation ([#193](../../issues/193))
* Added support for `ns` argument in `os.utime()` (Python >= 3.3) ([#192](../../issues/192)).
* Added nanosecond time members in `os.stat_result` (Python >= 3.3) ([#196](../../issues/196)).

#### Infrastructure

#### Fixes


## Version 3.2
## [Version 3.2](https://pypi.python.org/pypi/pyfakefs/3.2)

#### New Features
* The `errors` argument is supported for `io.open()` and `os.open()`
Expand Down
106 changes: 74 additions & 32 deletions fake_filesystem_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,21 @@
from pyfakefs import fake_filesystem


def _GetDummyTime(start_time, increment):
def _DummyTime():
_DummyTime._curr_time += increment
return _DummyTime._curr_time
class _DummyTime(object):
"""Mock replacement for time.time. Increases returned time on access."""

_DummyTime._curr_time = start_time - increment # pylint: disable-msg=W0612
return _DummyTime
def __init__(self, curr_time, increment):
self.curr_time = curr_time
self.increment = increment
self.started = False

def start(self):
self.started = True

def __call__(self, *args, **kwargs):
if self.started:
self.curr_time += self.increment
return self.curr_time


class TestCase(unittest.TestCase):
Expand Down Expand Up @@ -67,7 +75,7 @@ def assertRaisesOSError(self, subtype, expression, *args, **kwargs):
class FakeDirectoryUnitTest(TestCase):
def setUp(self):
self.orig_time = time.time
time.time = _GetDummyTime(10, 1)
time.time = _DummyTime(10, 1)
self.fake_file = fake_filesystem.FakeFile('foobar', contents='dummy_file')
self.fake_dir = fake_filesystem.FakeDirectory('somedir')

Expand Down Expand Up @@ -676,7 +684,7 @@ def setUp(self):
self.rwx = self.os.R_OK | self.os.W_OK | self.os.X_OK
self.rw = self.os.R_OK | self.os.W_OK
self.orig_time = time.time
time.time = _GetDummyTime(200, 20)
time.time = _DummyTime(200, 20)

def tearDown(self):
time.time = self.orig_time
Expand Down Expand Up @@ -1717,6 +1725,8 @@ def testChmodStCtime(self):
file_path = 'some_file'
self.filesystem.CreateFile(file_path)
self.assertTrue(self.filesystem.Exists(file_path))
time.time.start()

st = self.os.stat(file_path)
self.assertEqual(200, st.st_ctime)
# tests
Expand All @@ -1728,6 +1738,8 @@ def testUtimeSetsCurrentTimeIfArgsIsNone(self):
# set up
path = '/some_file'
self._CreateTestFile(path)
time.time.start()

st = self.os.stat(path)
# 200 is the current time established in setUp().
self.assertEqual(200, st.st_atime)
Expand All @@ -1736,39 +1748,51 @@ def testUtimeSetsCurrentTimeIfArgsIsNone(self):
self.os.utime(path, None)
st = self.os.stat(path)
self.assertEqual(220, st.st_atime)
self.assertEqual(240, st.st_mtime)
self.assertEqual(220, st.st_mtime)

def testUtimeSetsCurrentTimeIfArgsIsNoneWithFloats(self):
# set up
# we set os.stat_float_times() to False, so atime/ctime/mtime
# are converted as ints (seconds since epoch)
time.time = _GetDummyTime(200.9123, 20)
time.time = _DummyTime(200.9123, 20)
path = '/some_file'
fake_filesystem.FakeOsModule.stat_float_times(False)
self._CreateTestFile(path)
time.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(240, st.st_mtime)
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 testUtimeSetsCurrentTimeIfArgsIsNoneWithFloatsNSec(self):
self.filesystem = fake_filesystem.FakeFilesystem(path_separator='/')
self.os = fake_filesystem.FakeOsModule(self.filesystem)
self.assertTrue(not self.os.stat_float_times())
fake_filesystem.FakeOsModule.stat_float_times(False)

time.time = _GetDummyTime(200.9123, 20)
time.time = _DummyTime(200.9123, 20)
path = '/some_file'
test_file = self._CreateTestFile(path)

time.time.start()
st = self.os.stat(path)
self.assertEqual(200, st.st_ctime)
self.assertEqual(200, test_file.st_ctime)
Expand Down Expand Up @@ -1796,7 +1820,7 @@ def testUtimeSetsCurrentTimeIfArgsIsNoneWithFloatsNSec(self):
self.os.utime(path, None)
st = self.os.stat(path)
self.assertEqual(220.9123, st.st_atime)
self.assertEqual(240.9123, st.st_mtime)
self.assertEqual(220.9123, st.st_mtime)

def testUtimeSetsSpecifiedTime(self):
# set up
Expand Down Expand Up @@ -1865,6 +1889,8 @@ def testUtimeSetsSpecifiedTimeInNs(self):
# set up
path = '/some_file'
self._CreateTestFile(path)
time.time.start()

st = self.os.stat(path)
# actual tests
self.os.utime(path, ns=(200000000, 400000000))
Expand Down Expand Up @@ -2358,6 +2384,12 @@ def testStat(self):
self.assertEqual(self.filesystem.ResolveObject('/linked/plugh/dir').st_mtime,
self.dir_entries[2].stat().st_mtime)

def testIndexAccessToStatTimesReturnsInt(self):
self.assertEqual(self.os.stat('/xyzzy/plugh/dir')[stat.ST_CTIME],
int(self.dir_entries[0].stat().st_ctime))
self.assertEqual(self.os.stat('/linked/plugh/dir')[stat.ST_MTIME],
int(self.dir_entries[2].stat().st_mtime))

def testStatInoDevPosix(self):
self.filesystem.is_windows_fs = False
file_obj = self.filesystem.ResolveObject('/linked/plugh/file')
Expand Down Expand Up @@ -2522,7 +2554,7 @@ def testCreateTopLevelDirectory(self):
class FakePathModuleTest(TestCase):
def setUp(self):
self.orig_time = time.time
time.time = _GetDummyTime(10, 1)
time.time = _DummyTime(10, 1)
self.filesystem = fake_filesystem.FakeFilesystem(path_separator='!')
self.os = fake_filesystem.FakeOsModule(self.filesystem)
self.path = self.os.path
Expand Down Expand Up @@ -2737,9 +2769,8 @@ def testIsfile(self):

def testGetMtime(self):
test_file = self.filesystem.CreateFile('foo!bar1.txt')
# The root directory ('', effectively '!') is created at time 10,
# the parent directory ('foo') at time 11, and the file at time 12.
self.assertEqual(12, test_file.st_mtime)
time.time.start()
self.assertEqual(10, test_file.st_mtime)
test_file.SetMTime(24)
self.assertEqual(24, self.path.getmtime('foo!bar1.txt'))

Expand Down Expand Up @@ -2908,7 +2939,7 @@ def setUp(self):
self.open = self.file
self.os = fake_filesystem.FakeOsModule(self.filesystem)
self.orig_time = time.time
time.time = _GetDummyTime(100, 10)
time.time = _DummyTime(100, 10)

def tearDown(self):
time.time = self.orig_time
Expand Down Expand Up @@ -3287,41 +3318,52 @@ def testOpenStCtime(self):
self.assertFalse(self.filesystem.Exists(file_path))
# tests
fake_file = self.file(file_path, 'w')
time.time.start()
st = self.os.stat(file_path)
self.assertEqual(100, st.st_ctime, st.st_mtime)
self.assertEqual(100, st.st_ctime)
self.assertEqual(100, st.st_mtime)
fake_file.close()
st = self.os.stat(file_path)
self.assertEqual(110, st.st_ctime, st.st_mtime)
self.assertEqual(110, st.st_ctime)
self.assertEqual(110, st.st_mtime)

fake_file = self.file(file_path, 'w')
st = self.os.stat(file_path)
# truncating the file cause an additional stat update
self.assertEqual(120, st.st_ctime, st.st_mtime)
self.assertEqual(120, st.st_ctime)
self.assertEqual(120, st.st_mtime)
fake_file.close()
st = self.os.stat(file_path)
self.assertEqual(130, st.st_ctime, st.st_mtime)
self.assertEqual(130, st.st_ctime)
self.assertEqual(130, st.st_mtime)

fake_file = self.file(file_path, 'w+')
st = self.os.stat(file_path)
self.assertEqual(140, st.st_ctime, st.st_mtime)
self.assertEqual(140, st.st_ctime)
self.assertEqual(140, st.st_mtime)
fake_file.close()
st = self.os.stat(file_path)
self.assertEqual(150, st.st_ctime, st.st_mtime)
self.assertEqual(150, st.st_ctime)
self.assertEqual(150, st.st_mtime)

fake_file = self.file(file_path, 'a')
st = self.os.stat(file_path)
# not updating m_time or c_time here, since no truncating.
self.assertEqual(150, st.st_ctime, st.st_mtime)
self.assertEqual(150, st.st_ctime)
self.assertEqual(150, st.st_mtime)
fake_file.close()
st = self.os.stat(file_path)
self.assertEqual(160, st.st_ctime, st.st_mtime)
self.assertEqual(160, st.st_ctime)
self.assertEqual(160, st.st_mtime)

fake_file = self.file(file_path, 'r')
st = self.os.stat(file_path)
self.assertEqual(160, st.st_ctime, st.st_mtime)
self.assertEqual(160, st.st_ctime)
self.assertEqual(160, st.st_mtime)
fake_file.close()
st = self.os.stat(file_path)
self.assertEqual(160, st.st_ctime, st.st_mtime)
self.assertEqual(160, st.st_ctime)
self.assertEqual(160, st.st_mtime)

def _CreateWithPermission(self, file_path, perm_bits):
self.filesystem.CreateFile(file_path)
Expand Down Expand Up @@ -4600,9 +4642,9 @@ def checkFakeFileStat(self, fake_file, 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.assertAlmostEqual(fake_file.st_ctime, real_stat.st_ctime, places=5)
self.assertAlmostEqual(fake_file.st_atime, real_stat.st_atime, places=5)
self.assertAlmostEqual(fake_file.st_mtime, real_stat.st_mtime, places=5)
self.assertEqual(fake_file.st_uid, real_stat.st_uid)
self.assertEqual(fake_file.st_gid, real_stat.st_gid)

Expand Down
6 changes: 3 additions & 3 deletions fake_filesystem_unittest_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,10 @@ def testCopyRealFile(self):

self.assertEqual(oct(fake_file.st_mode), oct(self.real_stat.st_mode))
self.assertEqual(fake_file.st_size, self.real_stat.st_size)
self.assertEqual(fake_file.st_ctime, self.real_stat.st_ctime)
self.assertGreaterEqual(fake_file.st_atime, self.real_stat.st_atime)
self.assertAlmostEqual(fake_file.st_ctime, self.real_stat.st_ctime, places=5)
self.assertAlmostEqual(fake_file.st_atime, self.real_stat.st_atime, places=5)
self.assertLess(fake_file.st_atime, self.real_stat.st_atime + 10)
self.assertEqual(fake_file.st_mtime, self.real_stat.st_mtime)
self.assertAlmostEqual(fake_file.st_mtime, self.real_stat.st_mtime, places=5)
self.assertEqual(fake_file.st_uid, self.real_stat.st_uid)
self.assertEqual(fake_file.st_gid, self.real_stat.st_gid)

Expand Down
21 changes: 11 additions & 10 deletions fake_pathlib_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,21 +235,22 @@ def test_stat(self):
file_object = self.filesystem.ResolveObject('/home/jane/test.py')

stat_result = self.path('/test.py').stat()
self.assertFalse(stat_result[stat.ST_MODE] & stat.S_IFDIR)
self.assertTrue(stat_result[stat.ST_MODE] & stat.S_IFREG)
self.assertEqual(stat_result[stat.ST_INO], file_object.st_ino)
self.assertEqual(stat_result[stat.ST_SIZE], 100)
self.assertEqual(stat_result[stat.ST_MTIME], file_object.st_mtime)
self.assertFalse(stat_result.st_mode & stat.S_IFDIR)
self.assertTrue(stat_result.st_mode & stat.S_IFREG)
self.assertEqual(stat_result.st_ino, file_object.st_ino)
self.assertEqual(stat_result.st_size, 100)
self.assertEqual(stat_result.st_mtime, file_object.st_mtime)
self.assertEqual(stat_result[stat.ST_MTIME], int(file_object.st_mtime))

def test_lstat(self):
link_object = self.filesystem.LResolveObject('/test.py')

stat_result = self.path('/test.py').lstat()
self.assertTrue(stat_result[stat.ST_MODE] & stat.S_IFREG)
self.assertTrue(stat_result[stat.ST_MODE] & stat.S_IFLNK)
self.assertEqual(stat_result[stat.ST_INO], link_object.st_ino)
self.assertEqual(stat_result[stat.ST_SIZE], len('/home/jane/test.py'))
self.assertEqual(stat_result[stat.ST_MTIME], link_object.st_mtime)
self.assertTrue(stat_result.st_mode & stat.S_IFREG)
self.assertTrue(stat_result.st_mode & stat.S_IFLNK)
self.assertEqual(stat_result.st_ino, link_object.st_ino)
self.assertEqual(stat_result.st_size, len('/home/jane/test.py'))
self.assertEqual(stat_result.st_mtime, link_object.st_mtime)

def test_chmod(self):
file_object = self.filesystem.ResolveObject('/home/jane/test.py')
Expand Down
Loading

0 comments on commit 6e2c752

Please sign in to comment.