summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_os.py
diff options
context:
space:
mode:
authorLarry Hastings <larry@hastings.org>2012-05-03 07:30:07 (GMT)
committerLarry Hastings <larry@hastings.org>2012-05-03 07:30:07 (GMT)
commit76ad59b7e826691e0eb19f04cb647e07cdbde76a (patch)
tree3c775b67065ab0424b23367462d324648add4810 /Lib/test/test_os.py
parent3a7f7977f1ad3e5afe79254eef5057c0288613db (diff)
downloadcpython-76ad59b7e826691e0eb19f04cb647e07cdbde76a.zip
cpython-76ad59b7e826691e0eb19f04cb647e07cdbde76a.tar.gz
cpython-76ad59b7e826691e0eb19f04cb647e07cdbde76a.tar.bz2
Issue #14127: Add ns= parameter to utime, futimes, and lutimes.
Removed futimens as it is now redundant. Changed shutil.copystat to use st_atime_ns and st_mtime_ns from os.stat and ns= parameter to utime--it once again preserves exact metadata on Linux!
Diffstat (limited to 'Lib/test/test_os.py')
-rw-r--r--Lib/test/test_os.py86
1 files changed, 72 insertions, 14 deletions
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index aa619a8..0c15f22 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -192,11 +192,11 @@ class StatAttributeTests(unittest.TestCase):
self.assertIn(attr, members)
# Make sure that the st_?time and st_?time_ns fields roughly agree
- # (they should always agree up to the tens-of-microseconds magnitude)
+ # (they should always agree up to around tens-of-microseconds)
for name in 'st_atime st_mtime st_ctime'.split():
floaty = int(getattr(result, name) * 100000)
nanosecondy = getattr(result, name + "_ns") // 10000
- self.assertEqual(floaty, nanosecondy)
+ self.assertAlmostEqual(floaty, nanosecondy, delta=2)
try:
result[200]
@@ -303,20 +303,80 @@ class StatAttributeTests(unittest.TestCase):
st2 = os.stat(support.TESTFN)
self.assertEqual(st2.st_mtime, int(st.st_mtime-delta))
- def test_utime_noargs(self):
+ def _test_utime(self, filename, attr, utime, delta):
# Issue #13327 removed the requirement to pass None as the
# second argument. Check that the previous methods of passing
# a time tuple or None work in addition to no argument.
- st = os.stat(support.TESTFN)
+ st0 = os.stat(filename)
# Doesn't set anything new, but sets the time tuple way
- os.utime(support.TESTFN, (st.st_atime, st.st_mtime))
+ utime(filename, (attr(st0, "st_atime"), attr(st0, "st_mtime")))
+ # Setting the time to the time you just read, then reading again,
+ # should always return exactly the same times.
+ st1 = os.stat(filename)
+ self.assertEqual(attr(st0, "st_mtime"), attr(st1, "st_mtime"))
+ self.assertEqual(attr(st0, "st_atime"), attr(st1, "st_atime"))
# Set to the current time in the old explicit way.
- os.utime(support.TESTFN, None)
- st1 = os.stat(support.TESTFN)
- # Set to the current time in the new way
- os.utime(support.TESTFN)
+ os.utime(filename, None)
st2 = os.stat(support.TESTFN)
- self.assertAlmostEqual(st1.st_mtime, st2.st_mtime, delta=10)
+ # Set to the current time in the new way
+ os.utime(filename)
+ st3 = os.stat(filename)
+ self.assertAlmostEqual(attr(st2, "st_mtime"), attr(st3, "st_mtime"), delta=delta)
+
+ def test_utime(self):
+ def utime(file, times):
+ return os.utime(file, times)
+ self._test_utime(self.fname, getattr, utime, 10)
+ self._test_utime(support.TESTFN, getattr, utime, 10)
+
+
+ def _test_utime_ns(self, set_times_ns, test_dir=True):
+ def getattr_ns(o, attr):
+ return getattr(o, attr + "_ns")
+ ten_s = 10 * 1000 * 1000 * 1000
+ self._test_utime(self.fname, getattr_ns, set_times_ns, ten_s)
+ if test_dir:
+ self._test_utime(support.TESTFN, getattr_ns, set_times_ns, ten_s)
+
+ def test_utime_ns(self):
+ def utime_ns(file, times):
+ return os.utime(file, ns=times)
+ self._test_utime_ns(utime_ns)
+
+ requires_lutimes = unittest.skipUnless(hasattr(os, 'lutimes'),
+ "os.lutimes required for this test.")
+ requires_futimes = unittest.skipUnless(hasattr(os, 'futimes'),
+ "os.futimes required for this test.")
+
+ @requires_lutimes
+ def test_lutimes_ns(self):
+ def lutimes_ns(file, times):
+ return os.lutimes(file, ns=times)
+ self._test_utime_ns(lutimes_ns)
+
+ @requires_futimes
+ def test_futimes_ns(self):
+ def futimes_ns(file, times):
+ with open(file, "wb") as f:
+ os.futimes(f.fileno(), ns=times)
+ self._test_utime_ns(futimes_ns, test_dir=False)
+
+ def _utime_invalid_arguments(self, name, arg):
+ with self.assertRaises(RuntimeError):
+ getattr(os, name)(arg, (5, 5), ns=(5, 5))
+
+ def test_utime_invalid_arguments(self):
+ self._utime_invalid_arguments('utime', self.fname)
+
+ @requires_lutimes
+ def test_lutimes_invalid_arguments(self):
+ self._utime_invalid_arguments('lutimes', self.fname)
+
+ @requires_futimes
+ def test_futimes_invalid_arguments(self):
+ with open(self.fname, "wb") as f:
+ self._utime_invalid_arguments('futimes', f.fileno())
+
@unittest.skipUnless(stat_supports_subsecond,
"os.stat() doesn't has a subsecond resolution")
@@ -338,8 +398,7 @@ class StatAttributeTests(unittest.TestCase):
os.utime(filename, (atime, mtime))
self._test_utime_subsecond(set_time)
- @unittest.skipUnless(hasattr(os, 'futimes'),
- "os.futimes required for this test.")
+ @requires_futimes
def test_futimes_subsecond(self):
def set_time(filename, atime, mtime):
with open(filename, "wb") as f:
@@ -375,8 +434,7 @@ class StatAttributeTests(unittest.TestCase):
os.close(dirfd)
self._test_utime_subsecond(set_time)
- @unittest.skipUnless(hasattr(os, 'lutimes'),
- "os.lutimes required for this test.")
+ @requires_lutimes
def test_lutimes_subsecond(self):
def set_time(filename, atime, mtime):
os.lutimes(filename, (atime, mtime))