~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_osutils.py

Add a NEWS entry and prepare submission.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
21
21
import os
22
22
import re
23
23
import socket
 
24
import stat
24
25
import sys
25
26
import time
26
27
 
27
28
from bzrlib import (
28
29
    errors,
29
 
    lazy_regex,
30
30
    osutils,
31
 
    symbol_versioning,
32
31
    tests,
33
32
    trace,
34
33
    win32utils,
35
34
    )
36
35
from bzrlib.tests import (
37
 
    features,
38
36
    file_utils,
39
37
    test__walkdirs_win32,
40
38
    )
55
53
 
56
54
UTF8DirReaderFeature = _UTF8DirReaderFeature()
57
55
 
58
 
term_ios_feature = tests.ModuleAvailableFeature('termios')
 
56
TermIOSFeature = tests.ModuleAvailableFeature('termios')
59
57
 
60
58
 
61
59
def _already_unicode(s):
84
82
                          dict(_dir_reader_class=_readdir_pyx.UTF8DirReader,
85
83
                               _native_to_unicode=_utf8_to_unicode)))
86
84
 
87
 
    if test__walkdirs_win32.win32_readdir_feature.available():
 
85
    if test__walkdirs_win32.Win32ReadDirFeature.available():
88
86
        try:
89
87
            from bzrlib import _walkdirs_win32
90
88
            scenarios.append(
311
309
        self.assertEqual("/", osutils.kind_marker(osutils._directory_kind))
312
310
        self.assertEqual("@", osutils.kind_marker("symlink"))
313
311
        self.assertEqual("+", osutils.kind_marker("tree-reference"))
314
 
        self.assertEqual("", osutils.kind_marker("fifo"))
315
 
        self.assertEqual("", osutils.kind_marker("socket"))
316
 
        self.assertEqual("", osutils.kind_marker("unknown"))
 
312
        self.assertRaises(errors.BzrError, osutils.kind_marker, "unknown")
317
313
 
318
314
 
319
315
class TestUmask(tests.TestCaseInTempDir):
862
858
        self.assertEqual('//HOST/path', osutils._win98_abspath('//HOST/path'))
863
859
        # relative path
864
860
        cwd = osutils.getcwd().rstrip('/')
865
 
        drive = osutils.ntpath.splitdrive(cwd)[0]
 
861
        drive = osutils._nt_splitdrive(cwd)[0]
866
862
        self.assertEqual(cwd+'/path', osutils._win98_abspath('path'))
867
863
        self.assertEqual(drive+'/path', osutils._win98_abspath('/path'))
868
864
        # unicode path
993
989
 
994
990
    def test_osutils_binding(self):
995
991
        from bzrlib.tests import test__chunks_to_lines
996
 
        if test__chunks_to_lines.compiled_chunkstolines_feature.available():
 
992
        if test__chunks_to_lines.CompiledChunksToLinesFeature.available():
997
993
            from bzrlib._chunks_to_lines_pyx import chunks_to_lines
998
994
        else:
999
995
            from bzrlib._chunks_to_lines_py import chunks_to_lines
1065
1061
        self.assertExpectedBlocks(expected_dirblocks[1:], result)
1066
1062
 
1067
1063
    def test_walkdirs_os_error(self):
1068
 
        # <https://bugs.launchpad.net/bzr/+bug/338653>
 
1064
        # <https://bugs.edge.launchpad.net/bzr/+bug/338653>
1069
1065
        # Pyrex readdir didn't raise useful messages if it had an error
1070
1066
        # reading the directory
1071
1067
        if sys.platform == 'win32':
1072
1068
            raise tests.TestNotApplicable(
1073
1069
                "readdir IOError not tested on win32")
1074
 
        self.requireFeature(features.not_running_as_root)
1075
1070
        os.mkdir("test-unreadable")
1076
1071
        os.chmod("test-unreadable", 0000)
1077
1072
        # must chmod it back so that it can be removed
1085
1080
        # Ensure the message contains the file name
1086
1081
        self.assertContainsRe(str(e), "\./test-unreadable")
1087
1082
 
1088
 
 
1089
 
    def test_walkdirs_encoding_error(self):
1090
 
        # <https://bugs.launchpad.net/bzr/+bug/488519>
1091
 
        # walkdirs didn't raise a useful message when the filenames
1092
 
        # are not using the filesystem's encoding
1093
 
 
1094
 
        # require a bytestring based filesystem
1095
 
        self.requireFeature(tests.ByteStringNamedFilesystem)
1096
 
 
1097
 
        tree = [
1098
 
            '.bzr',
1099
 
            '0file',
1100
 
            '1dir/',
1101
 
            '1dir/0file',
1102
 
            '1dir/1dir/',
1103
 
            '1file'
1104
 
            ]
1105
 
 
1106
 
        self.build_tree(tree)
1107
 
 
1108
 
        # rename the 1file to a latin-1 filename
1109
 
        os.rename("./1file", "\xe8file")
1110
 
 
1111
 
        self._save_platform_info()
1112
 
        win32utils.winver = None # Avoid the win32 detection code
1113
 
        osutils._fs_enc = 'UTF-8'
1114
 
 
1115
 
        # this should raise on error
1116
 
        def attempt():
1117
 
            for dirdetail, dirblock in osutils.walkdirs('.'):
1118
 
                pass
1119
 
 
1120
 
        self.assertRaises(errors.BadFilenameEncoding, attempt)
1121
 
 
1122
1083
    def test__walkdirs_utf8(self):
1123
1084
        tree = [
1124
1085
            '.bzr',
1174
1135
            dirblock[:] = new_dirblock
1175
1136
 
1176
1137
    def _save_platform_info(self):
1177
 
        self.overrideAttr(win32utils, 'winver')
1178
 
        self.overrideAttr(osutils, '_fs_enc')
1179
 
        self.overrideAttr(osutils, '_selected_dir_reader')
 
1138
        cur_winver = win32utils.winver
 
1139
        cur_fs_enc = osutils._fs_enc
 
1140
        cur_dir_reader = osutils._selected_dir_reader
 
1141
        def restore():
 
1142
            win32utils.winver = cur_winver
 
1143
            osutils._fs_enc = cur_fs_enc
 
1144
            osutils._selected_dir_reader = cur_dir_reader
 
1145
        self.addCleanup(restore)
1180
1146
 
1181
1147
    def assertDirReaderIs(self, expected):
1182
1148
        """Assert the right implementation for _walkdirs_utf8 is chosen."""
1215
1181
 
1216
1182
    def test_force_walkdirs_utf8_nt(self):
1217
1183
        # Disabled because the thunk of the whole walkdirs api is disabled.
1218
 
        self.requireFeature(test__walkdirs_win32.win32_readdir_feature)
 
1184
        self.requireFeature(test__walkdirs_win32.Win32ReadDirFeature)
1219
1185
        self._save_platform_info()
1220
1186
        win32utils.winver = 'Windows NT'
1221
1187
        from bzrlib._walkdirs_win32 import Win32ReadDir
1222
1188
        self.assertDirReaderIs(Win32ReadDir)
1223
1189
 
1224
1190
    def test_force_walkdirs_utf8_98(self):
1225
 
        self.requireFeature(test__walkdirs_win32.win32_readdir_feature)
 
1191
        self.requireFeature(test__walkdirs_win32.Win32ReadDirFeature)
1226
1192
        self._save_platform_info()
1227
1193
        win32utils.winver = 'Windows 98'
1228
1194
        self.assertDirReaderIs(osutils.UnicodeDirReader)
1379
1345
        self.assertEqual(expected_dirblocks, result)
1380
1346
 
1381
1347
    def test__walkdirs_utf8_win32readdir(self):
1382
 
        self.requireFeature(test__walkdirs_win32.win32_readdir_feature)
 
1348
        self.requireFeature(test__walkdirs_win32.Win32ReadDirFeature)
1383
1349
        self.requireFeature(tests.UnicodeFilenameFeature)
1384
1350
        from bzrlib._walkdirs_win32 import Win32ReadDir
1385
1351
        self._save_platform_info()
1436
1402
 
1437
1403
    def test__walkdirs_utf_win32_find_file_stat_file(self):
1438
1404
        """make sure our Stat values are valid"""
1439
 
        self.requireFeature(test__walkdirs_win32.win32_readdir_feature)
 
1405
        self.requireFeature(test__walkdirs_win32.Win32ReadDirFeature)
1440
1406
        self.requireFeature(tests.UnicodeFilenameFeature)
1441
1407
        from bzrlib._walkdirs_win32 import Win32ReadDir
1442
1408
        name0u = u'0file-\xb6'
1460
1426
 
1461
1427
    def test__walkdirs_utf_win32_find_file_stat_directory(self):
1462
1428
        """make sure our Stat values are valid"""
1463
 
        self.requireFeature(test__walkdirs_win32.win32_readdir_feature)
 
1429
        self.requireFeature(test__walkdirs_win32.Win32ReadDirFeature)
1464
1430
        self.requireFeature(tests.UnicodeFilenameFeature)
1465
1431
        from bzrlib._walkdirs_win32 import Win32ReadDir
1466
1432
        name0u = u'0dir-\u062c\u0648'
1615
1581
        def cleanup():
1616
1582
            if 'BZR_TEST_ENV_VAR' in os.environ:
1617
1583
                del os.environ['BZR_TEST_ENV_VAR']
 
1584
 
1618
1585
        self.addCleanup(cleanup)
1619
1586
 
1620
1587
    def test_set(self):
1707
1674
 
1708
1675
class TestReCompile(tests.TestCase):
1709
1676
 
1710
 
    def _deprecated_re_compile_checked(self, *args, **kwargs):
1711
 
        return self.applyDeprecated(symbol_versioning.deprecated_in((2, 2, 0)),
1712
 
            osutils.re_compile_checked, *args, **kwargs)
1713
 
 
1714
1677
    def test_re_compile_checked(self):
1715
 
        r = self._deprecated_re_compile_checked(r'A*', re.IGNORECASE)
 
1678
        r = osutils.re_compile_checked(r'A*', re.IGNORECASE)
1716
1679
        self.assertTrue(r.match('aaaa'))
1717
1680
        self.assertTrue(r.match('aAaA'))
1718
1681
 
1719
1682
    def test_re_compile_checked_error(self):
1720
1683
        # like https://bugs.launchpad.net/bzr/+bug/251352
1721
 
 
1722
 
        # Due to possible test isolation error, re.compile is not lazy at
1723
 
        # this point. We re-install lazy compile.
1724
 
        lazy_regex.install_lazy_compile()
1725
1684
        err = self.assertRaises(
1726
1685
            errors.BzrCommandError,
1727
 
            self._deprecated_re_compile_checked, '*', re.IGNORECASE, 'test case')
 
1686
            osutils.re_compile_checked, '*', re.IGNORECASE, 'test case')
1728
1687
        self.assertEqual(
1729
 
            'Invalid regular expression in test case: '
1730
 
            '"*" nothing to repeat',
 
1688
            "Invalid regular expression in test case: '*': "
 
1689
            "nothing to repeat",
1731
1690
            str(err))
1732
1691
 
1733
1692
 
1739
1698
 
1740
1699
    def setUp(self):
1741
1700
        tests.TestCaseInTempDir.setUp(self)
1742
 
        self.overrideAttr(osutils,
1743
 
                          '_selected_dir_reader', self._dir_reader_class())
 
1701
 
 
1702
        # Save platform specific info and reset it
 
1703
        cur_dir_reader = osutils._selected_dir_reader
 
1704
 
 
1705
        def restore():
 
1706
            osutils._selected_dir_reader = cur_dir_reader
 
1707
        self.addCleanup(restore)
 
1708
 
 
1709
        osutils._selected_dir_reader = self._dir_reader_class()
1744
1710
 
1745
1711
    def _get_ascii_tree(self):
1746
1712
        tree = [
1893
1859
 
1894
1860
    def setUp(self):
1895
1861
        super(TestConcurrency, self).setUp()
1896
 
        self.overrideAttr(osutils, '_cached_local_concurrency')
 
1862
        orig = osutils._cached_local_concurrency
 
1863
        def restore():
 
1864
            osutils._cached_local_concurrency = orig
 
1865
        self.addCleanup(restore)
1897
1866
 
1898
1867
    def test_local_concurrency(self):
1899
1868
        concurrency = osutils.local_concurrency()
1926
1895
 
1927
1896
    def setUp(self):
1928
1897
        super(TestFailedToLoadExtension, self).setUp()
1929
 
        self.overrideAttr(osutils, '_extension_load_failures', [])
 
1898
        self.saved_failures = osutils._extension_load_failures[:]
 
1899
        del osutils._extension_load_failures[:]
 
1900
        self.addCleanup(self.restore_failures)
 
1901
 
 
1902
    def restore_failures(self):
 
1903
        osutils._extension_load_failures = self.saved_failures
1930
1904
 
1931
1905
    def test_failure_to_load(self):
1932
1906
        self._try_loading()
1954
1928
 
1955
1929
class TestTerminalWidth(tests.TestCase):
1956
1930
 
1957
 
    def setUp(self):
1958
 
        tests.TestCase.setUp(self)
1959
 
        self._orig_terminal_size_state = osutils._terminal_size_state
1960
 
        self._orig_first_terminal_size = osutils._first_terminal_size
1961
 
        self.addCleanup(self.restore_osutils_globals)
1962
 
        osutils._terminal_size_state = 'no_data'
1963
 
        osutils._first_terminal_size = None
1964
 
 
1965
 
    def restore_osutils_globals(self):
1966
 
        osutils._terminal_size_state = self._orig_terminal_size_state
1967
 
        osutils._first_terminal_size = self._orig_first_terminal_size
1968
 
 
1969
1931
    def replace_stdout(self, new):
1970
 
        self.overrideAttr(sys, 'stdout', new)
 
1932
        orig_stdout = sys.stdout
 
1933
        def restore():
 
1934
            sys.stdout = orig_stdout
 
1935
        self.addCleanup(restore)
 
1936
        sys.stdout = new
1971
1937
 
1972
1938
    def replace__terminal_size(self, new):
1973
 
        self.overrideAttr(osutils, '_terminal_size', new)
 
1939
        orig__terminal_size = osutils._terminal_size
 
1940
        def restore():
 
1941
            osutils._terminal_size = orig__terminal_size
 
1942
        self.addCleanup(restore)
 
1943
        osutils._terminal_size = new
1974
1944
 
1975
1945
    def set_fake_tty(self):
1976
1946
 
2017
1987
        self.assertEqual(None, osutils.terminal_width())
2018
1988
 
2019
1989
    def test_no_TIOCGWINSZ(self):
2020
 
        self.requireFeature(term_ios_feature)
2021
 
        termios = term_ios_feature.module
 
1990
        self.requireFeature(TermIOSFeature)
 
1991
        termios = TermIOSFeature.module
2022
1992
        # bug 63539 is about a termios without TIOCGWINSZ attribute
2023
1993
        try:
2024
1994
            orig = termios.TIOCGWINSZ
2026
1996
            # We won't remove TIOCGWINSZ, because it doesn't exist anyway :)
2027
1997
            pass
2028
1998
        else:
2029
 
            self.overrideAttr(termios, 'TIOCGWINSZ')
 
1999
            def restore():
 
2000
                termios.TIOCGWINSZ = orig
 
2001
            self.addCleanup(restore)
2030
2002
            del termios.TIOCGWINSZ
2031
2003
        del os.environ['BZR_COLUMNS']
2032
2004
        del os.environ['COLUMNS']
2033
2005
        # Whatever the result is, if we don't raise an exception, it's ok.
2034
2006
        osutils.terminal_width()
2035
 
 
2036
 
class TestCreationOps(tests.TestCaseInTempDir):
2037
 
    _test_needs_features = [features.chown_feature]
2038
 
 
2039
 
    def setUp(self):
2040
 
        tests.TestCaseInTempDir.setUp(self)
2041
 
        self.overrideAttr(os, 'chown', self._dummy_chown)
2042
 
 
2043
 
        # params set by call to _dummy_chown
2044
 
        self.path = self.uid = self.gid = None
2045
 
 
2046
 
    def _dummy_chown(self, path, uid, gid):
2047
 
        self.path, self.uid, self.gid = path, uid, gid
2048
 
 
2049
 
    def test_copy_ownership_from_path(self):
2050
 
        """copy_ownership_from_path test with specified src."""
2051
 
        ownsrc = '/'
2052
 
        f = open('test_file', 'wt')
2053
 
        osutils.copy_ownership_from_path('test_file', ownsrc)
2054
 
 
2055
 
        s = os.stat(ownsrc)
2056
 
        self.assertEquals(self.path, 'test_file')
2057
 
        self.assertEquals(self.uid, s.st_uid)
2058
 
        self.assertEquals(self.gid, s.st_gid)
2059
 
 
2060
 
    def test_copy_ownership_nonesrc(self):
2061
 
        """copy_ownership_from_path test with src=None."""
2062
 
        f = open('test_file', 'wt')
2063
 
        # should use parent dir for permissions
2064
 
        osutils.copy_ownership_from_path('test_file')
2065
 
 
2066
 
        s = os.stat('..')
2067
 
        self.assertEquals(self.path, 'test_file')
2068
 
        self.assertEquals(self.uid, s.st_uid)
2069
 
        self.assertEquals(self.gid, s.st_gid)
2070
 
 
2071
 
class TestGetuserUnicode(tests.TestCase):
2072
 
 
2073
 
    def test_ascii_user(self):
2074
 
        osutils.set_or_unset_env('LOGNAME', 'jrandom')
2075
 
        self.assertEqual(u'jrandom', osutils.getuser_unicode())
2076
 
 
2077
 
    def test_unicode_user(self):
2078
 
        ue = osutils.get_user_encoding()
2079
 
        uni_val, env_val = tests.probe_unicode_in_user_encoding()
2080
 
        if uni_val is None:
2081
 
            raise tests.TestSkipped(
2082
 
                'Cannot find a unicode character that works in encoding %s'
2083
 
                % (osutils.get_user_encoding(),))
2084
 
        uni_username = u'jrandom' + uni_val
2085
 
        encoded_username = uni_username.encode(ue)
2086
 
        osutils.set_or_unset_env('LOGNAME', encoded_username)
2087
 
        self.assertEqual(uni_username, osutils.getuser_unicode())
2088
 
        osutils.set_or_unset_env('LOGNAME', u'jrandom\xb6'.encode(ue))
2089
 
        self.assertEqual(u'jrandom\xb6', osutils.getuser_unicode())
2090
 
 
2091
 
class TestBackupNames(tests.TestCase):
2092
 
 
2093
 
    def setUp(self):
2094
 
        super(TestBackupNames, self).setUp()
2095
 
        self.backups = []
2096
 
 
2097
 
    def backup_exists(self, name):
2098
 
        return name in self.backups
2099
 
 
2100
 
    def available_backup_name(self, name):
2101
 
        backup_name = osutils.available_backup_name(name, self.backup_exists)
2102
 
        self.backups.append(backup_name)
2103
 
        return backup_name
2104
 
 
2105
 
    def assertBackupName(self, expected, name):
2106
 
        self.assertEqual(expected, self.available_backup_name(name))
2107
 
 
2108
 
    def test_empty(self):
2109
 
        self.assertBackupName('file.~1~', 'file')
2110
 
 
2111
 
    def test_existing(self):
2112
 
        self.available_backup_name('file')
2113
 
        self.available_backup_name('file')
2114
 
        self.assertBackupName('file.~3~', 'file')
2115
 
        # Empty slots are found, this is not a strict requirement and may be
2116
 
        # revisited if we test against all implementations.
2117
 
        self.backups.remove('file.~2~')
2118
 
        self.assertBackupName('file.~2~', 'file')