Rev 2326: First set of tests for path_info working - unicode, native paths, missing paths, and pack_stat results. in file:///home/robertc/source/baz/dirstate2/
Robert Collins
robertc at robertcollins.net
Fri Mar 9 06:16:10 GMT 2007
At file:///home/robertc/source/baz/dirstate2/
------------------------------------------------------------
revno: 2326
revision-id: robertc at robertcollins.net-20070309061608-pau0d6iy2rss65lg
parent: robertc at robertcollins.net-20070309042352-6gabe2550go95z2d
committer: Robert Collins <robertc at robertcollins.net>
branch nick: dirstate2
timestamp: Fri 2007-03-09 17:16:08 +1100
message:
First set of tests for path_info working - unicode, native paths, missing paths, and pack_stat results.
modified:
bzrlib/osutils.py osutils.py-20050309040759-eeaff12fbf77ac86
bzrlib/path_info.py path_info.py-20070309041626-f8val8ukxzzzyudi-1
bzrlib/path_info_python.py path_info_python.py-20070309041626-f8val8ukxzzzyudi-2
bzrlib/tests/path_info_implementations/test_path_info.py test_path_info.py-20070309041626-f8val8ukxzzzyudi-5
=== modified file 'bzrlib/osutils.py'
--- a/bzrlib/osutils.py 2007-03-07 01:14:11 +0000
+++ b/bzrlib/osutils.py 2007-03-09 06:16:08 +0000
@@ -102,28 +102,7 @@
return f
-_directory_kind = 'directory'
-
-_formats = {
- stat.S_IFDIR:_directory_kind,
- stat.S_IFCHR:'chardev',
- stat.S_IFBLK:'block',
- stat.S_IFREG:'file',
- stat.S_IFIFO:'fifo',
- stat.S_IFLNK:'symlink',
- stat.S_IFSOCK:'socket',
-}
-
-
-def file_kind_from_stat_mode(stat_mode, _formats=_formats, _unknown='unknown'):
- """Generate a file kind from a stat mode. This is used in walkdirs.
-
- Its performance is critical: Do not mutate without careful benchmarking.
- """
- try:
- return _formats[stat_mode & 0170000]
- except KeyError:
- return _unknown
+from path_info import _directory_kind, _formats, file_kind_from_stat_mode
def file_kind(f, _lstat=os.lstat, _mapper=file_kind_from_stat_mode):
=== modified file 'bzrlib/path_info.py'
--- a/bzrlib/path_info.py 2007-03-09 04:23:52 +0000
+++ b/bzrlib/path_info.py 2007-03-09 06:16:08 +0000
@@ -16,9 +16,51 @@
"""Functions for accessing data about paths."""
-from path_info_python import *
+__all__ = ['kind_file', 'kind_missing', 'pack_stat', 'path_info']
+
+import stat
def _test_modules():
import bzrlib.path_info_python
- # todo, look for the C module.
- return [bzrlib.path_info_python]
+ result = [bzrlib.path_info_python]
+ try:
+ import bzrlib.path_info_c
+ result.append(bzrlib.path_info_c)
+ except ImportError:
+ pass
+ return result
+
+
+# singletons for talking about kinds. These should not be replaced
+# by implementation modules; even though its possible to do so.
+kind_file = 'file'
+kind_missing = 'missing'
+_directory_kind = 'directory'
+
+_formats = {
+ stat.S_IFDIR:_directory_kind,
+ stat.S_IFCHR:'chardev',
+ stat.S_IFBLK:'block',
+ stat.S_IFREG:kind_file,
+ stat.S_IFIFO:'fifo',
+ stat.S_IFLNK:'symlink',
+ stat.S_IFSOCK:'socket',
+}
+
+
+def file_kind_from_stat_mode(stat_mode, _formats=_formats, _unknown='unknown'):
+ """Generate a file kind from a stat mode. This is used in walkdirs.
+
+ Its performance is critical: Do not mutate without careful benchmarking.
+ """
+ try:
+ return _formats[stat_mode & 0170000]
+ except KeyError:
+ return _unknown
+
+
+# at the end to avoid circular import issues
+try:
+ from bzrlib.path_info_c import *
+except ImportError:
+ from bzrlib.path_info_python import *
=== modified file 'bzrlib/path_info_python.py'
--- a/bzrlib/path_info_python.py 2007-03-09 04:23:52 +0000
+++ b/bzrlib/path_info_python.py 2007-03-09 06:16:08 +0000
@@ -19,10 +19,19 @@
This is the pure python implementation.
"""
-__all__ = ['pack_stat']
+__all__ = ['pack_stat', 'path_info']
import base64
+import errno
+import os
+import stat
import struct
+import sys
+
+# import from the imported path_info module, which has not yet been assigned
+# into bzrlib.
+file_kind_from_stat_mode = sys.modules['bzrlib.path_info'].file_kind_from_stat_mode
+kind_missing = sys.modules['bzrlib.path_info'].kind_missing
def pack_stat(st, _encode=base64.encodestring, _pack=struct.pack):
@@ -37,3 +46,20 @@
return _encode(_pack('>llllll'
, st.st_size, int(st.st_mtime), int(st.st_ctime)
, st.st_dev, st.st_ino, st.st_mode))[:-1]
+
+
+def path_info(abspath, _lstat=os.lstat, _mapper=file_kind_from_stat_mode,
+ _S_IEXEC=stat.S_IEXEC, _ENOENT=errno.ENOENT, _kind_missing=kind_missing):
+ """Get the kind, size, executability and statcache key for abspath."""
+ assert abspath.__class__ == str
+ try:
+ st = _lstat(abspath)
+ except OSError, e:
+ if e.errno != _ENOENT:
+ raise
+ else:
+ # TODO: could make this a constant to return, if we expect it to be
+ # common.
+ return (_kind_missing, 0, False, '')
+ return (_mapper(st.st_mode), st.st_size, bool(_S_IEXEC & st.st_mode),
+ pack_stat(st))
=== modified file 'bzrlib/tests/path_info_implementations/test_path_info.py'
--- a/bzrlib/tests/path_info_implementations/test_path_info.py 2007-03-09 04:23:52 +0000
+++ b/bzrlib/tests/path_info_implementations/test_path_info.py 2007-03-09 06:16:08 +0000
@@ -16,18 +16,67 @@
"""This tests the most primitive path_info call - path_info(abspath)."""
-import os
+import os.path
+import stat
+import sys
+from bzrlib import osutils
+from bzrlib.path_info import *
from bzrlib.tests import TestCaseInTempDir
class TestPathInfo(TestCaseInTempDir):
- def disabled_test_info_file_non_utf8(self):
+ def test_info_file_non_utf8(self):
# a simple non-utf, non-executable test that should pass on all
# platforms.
self.build_tree(['file'])
- result = self.path_info.path_info(os.abspath('file'))
- stat = os.lstat(result)
- expected = ('file')
- self.assertEqual(expected, result)
+ result = self.path_info.path_info(os.path.abspath('file'))
+ stat = os.lstat('file')
+ expected = ('file', stat.st_size, False, pack_stat(stat))
+ self.assertEqual(expected, result)
+ self.assertIs(kind_file, result[0])
+
+ def test_info_file_non_utf8_executable(self):
+ if not osutils.supports_executable():
+ raise TestSkipped('platform does support executable bits.')
+ # a simple non-utf, executable test that should pass on all
+ # platforms supporting executable bits.
+ self.build_tree(['file'])
+ st = os.lstat('file')
+ # make the file executable for this user
+ os.chmod('file', st.st_mode | stat.S_IXUSR)
+ st = os.lstat('file')
+ result = self.path_info.path_info(os.path.abspath('file'))
+ expected = ('file', st.st_size, True, pack_stat(st))
+ self.assertEqual(expected, result)
+ self.assertIs(kind_file, result[0])
+
+ def test_info_file_unicode(self):
+ # path_info should assert when asked for unicode paths.
+ self.assertRaises(AssertionError, self.path_info.path_info, u'foo')
+
+ def test_info_file_native(self):
+ # a non-executable test for all unicode supporting platforms.
+ # path_info expects to be called with a bytestring that is ready to
+ # hand to the os: this is to make C replacements easier.
+ try:
+ self.build_tree([u'\xe8file'])
+ except UnicodeEncodeError:
+ # not applicable on this platform.
+ return
+ encoding = sys.getfilesystemencoding()
+ encoded_name = u'\xe8file'.encode(encoding)
+ result = self.path_info.path_info(os.path.abspath(encoded_name))
+ stat = os.lstat(encoded_name)
+ expected = ('file', stat.st_size, False, pack_stat(stat))
+ self.assertEqual(expected, result)
+ self.assertIs(kind_file, result[0])
+
+ def test_info_absent_path(self):
+ # path_info should return a canned 'missing' kind for paths that are not
+ # present on disk.
+ result = self.path_info.path_info(os.path.abspath('missing-file'))
+ expected = ('missing', 0, False, '')
+ self.assertEqual(expected, result)
+ self.assertIs(kind_missing, result[0])
More information about the bazaar-commits
mailing list