added test coverage for distutils.dep_util, and cleaned up the module

This commit is contained in:
Tarek Ziadé 2009-12-10 15:29:03 +00:00
parent fd25634715
commit 1bd9b5e925
2 changed files with 132 additions and 37 deletions

View File

@ -9,29 +9,27 @@ __revision__ = "$Id$"
import os
from distutils.errors import DistutilsFileError
def newer(source, target):
"""Tells if the target is newer than the source.
def newer (source, target):
"""Return true if 'source' exists and is more recently modified than
'target', or if 'source' exists and 'target' doesn't. Return false if
both exist and 'target' is the same age or younger than 'source'.
Raise DistutilsFileError if 'source' does not exist.
Return true if 'source' exists and is more recently modified than
'target', or if 'source' exists and 'target' doesn't.
Return false if both exist and 'target' is the same age or younger
than 'source'. Raise DistutilsFileError if 'source' does not exist.
Note that this test is not very accurate: files created in the same second
will have the same "age".
"""
if not os.path.exists(source):
raise DistutilsFileError, ("file '%s' does not exist" %
os.path.abspath(source))
raise DistutilsFileError("file '%s' does not exist" %
os.path.abspath(source))
if not os.path.exists(target):
return 1
return True
from stat import ST_MTIME
mtime1 = os.stat(source)[ST_MTIME]
mtime2 = os.stat(target)[ST_MTIME]
return os.stat(source).st_mtime > os.stat(target).st_mtime
return mtime1 > mtime2
# newer ()
def newer_pairwise (sources, targets):
def newer_pairwise(sources, targets):
"""Walk two filename lists in parallel, testing if each source is newer
than its corresponding target. Return a pair of lists (sources,
targets) where source is newer than target, according to the semantics
@ -43,19 +41,18 @@ def newer_pairwise (sources, targets):
# build a pair of lists (sources, targets) where source is newer
n_sources = []
n_targets = []
for i in range(len(sources)):
if newer(sources[i], targets[i]):
n_sources.append(sources[i])
n_targets.append(targets[i])
for source, target in zip(sources, targets):
if newer(source, target):
n_sources.append(source)
n_targets.append(target)
return (n_sources, n_targets)
return n_sources, n_targets
# newer_pairwise ()
def newer_group (sources, target, missing='error'):
def newer_group(sources, target, missing='error'):
"""Return true if 'target' is out-of-date with respect to any file
listed in 'sources'. In other words, if 'target' exists and is newer
listed in 'sources'.
In other words, if 'target' exists and is newer
than every file in 'sources', return false; otherwise return true.
'missing' controls what we do when a source file is missing; the
default ("error") is to blow up with an OSError from inside 'stat()';
@ -68,14 +65,14 @@ def newer_group (sources, target, missing='error'):
"""
# If the target doesn't even exist, then it's definitely out-of-date.
if not os.path.exists(target):
return 1
return True
# Otherwise we have to find out the hard way: if *any* source file
# is more recent than 'target', then 'target' is out-of-date and
# we can immediately return true. If we fall through to the end
# of the loop, then 'target' is up-to-date and we return false.
from stat import ST_MTIME
target_mtime = os.stat(target)[ST_MTIME]
target_mtime = os.stat(target).st_mtime
for source in sources:
if not os.path.exists(source):
if missing == 'error': # blow up when we stat() the file
@ -83,12 +80,9 @@ def newer_group (sources, target, missing='error'):
elif missing == 'ignore': # missing source dropped from
continue # target's dependency list
elif missing == 'newer': # missing source means target is
return 1 # out-of-date
return True # out-of-date
source_mtime = os.stat(source)[ST_MTIME]
if source_mtime > target_mtime:
return 1
else:
return 0
if os.stat(source).st_mtime > target_mtime:
return True
# newer_group ()
return False

View File

@ -0,0 +1,101 @@
"""Tests for distutils.dep_util."""
import unittest
import os
import time
from distutils.dep_util import newer, newer_pairwise, newer_group
from distutils.errors import DistutilsFileError
from distutils.tests import support
# XXX needs to be tuned for the various platforms
_ST_MIME_TIMER = 1
class DepUtilTestCase(support.TempdirManager, unittest.TestCase):
def test_newer(self):
tmpdir = self.mkdtemp()
target = os.path.join(tmpdir, 'target')
source = os.path.join(tmpdir, 'source')
# Raise DistutilsFileError if 'source' does not exist.
self.assertRaises(DistutilsFileError, newer, target, source)
# Return true if 'source' exists and is more recently modified than
# 'target', or if 'source' exists and 'target' doesn't.
self.write_file(target)
self.assertTrue(newer(target, source))
self.write_file(source, 'xox')
time.sleep(_ST_MIME_TIMER) # ensures ST_MTIME differs
self.write_file(target, 'xhx')
self.assertTrue(newer(target, source))
# Return false if both exist and 'target' is the same age or younger
# than 'source'.
self.write_file(source, 'xox'); self.write_file(target, 'xhx')
self.assertFalse(newer(target, source))
self.write_file(target, 'xox')
time.sleep(_ST_MIME_TIMER)
self.write_file(source, 'xhx')
self.assertFalse(newer(target, source))
def test_newer_pairwise(self):
tmpdir = self.mkdtemp()
sources = os.path.join(tmpdir, 'sources')
targets = os.path.join(tmpdir, 'targets')
os.mkdir(sources)
os.mkdir(targets)
one = os.path.join(sources, 'one')
two = os.path.join(sources, 'two')
three = os.path.join(targets, 'three')
four = os.path.join(targets, 'four')
self.write_file(one)
self.write_file(three)
self.write_file(four)
time.sleep(_ST_MIME_TIMER)
self.write_file(two)
self.assertEquals(newer_pairwise([one, two], [three, four]),
([two],[four]))
def test_newer_group(self):
tmpdir = self.mkdtemp()
sources = os.path.join(tmpdir, 'sources')
os.mkdir(sources)
one = os.path.join(sources, 'one')
two = os.path.join(sources, 'two')
three = os.path.join(sources, 'three')
target = os.path.join(tmpdir, 'target')
# return true if 'target' is out-of-date with respect to any file
# listed in 'sources'.
self.write_file(target)
time.sleep(_ST_MIME_TIMER)
self.write_file(one)
self.write_file(two)
self.write_file(three)
self.assertTrue(newer_group([one, two, three], target))
self.write_file(one)
self.write_file(three)
self.write_file(two)
time.sleep(0.1)
self.write_file(target)
self.assertFalse(newer_group([one, two, three], target))
# missing handling
os.remove(one)
self.assertRaises(OSError, newer_group, [one, two, three], target)
self.assertFalse(newer_group([one, two, three], target,
missing='ignore'))
self.assertTrue(newer_group([one, two, three], target,
missing='newer'))
def test_suite():
return unittest.makeSuite(DepUtilTestCase)
if __name__ == "__main__":
unittest.main(defaultTest="test_suite")