~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_osutils.py

  • Committer: John Arbash Meinel
  • Date: 2008-07-11 21:41:24 UTC
  • mto: This revision was merged to the branch mainline in revision 3543.
  • Revision ID: john@arbash-meinel.com-20080711214124-qi09irlj7pd5cuzg
Shortcut the case when one revision is in the ancestry of the other.

At the cost of a heads() check, when one parent supersedes, we don't have to extract
the text for the other. Changes merge time from 3m37s => 3m21s. Using a
CachingParentsProvider would drop the time down to 3m11s.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007 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
16
16
 
17
17
"""Tests for the osutils wrapper."""
18
18
 
19
 
from cStringIO import StringIO
20
19
import errno
21
20
import os
22
21
import socket
23
22
import stat
24
23
import sys
25
 
import time
26
24
 
 
25
import bzrlib
27
26
from bzrlib import (
28
27
    errors,
29
28
    osutils,
30
 
    tests,
31
29
    win32utils,
32
30
    )
33
31
from bzrlib.errors import BzrBadParameterNotUnicode, InvalidURL
36
34
        is_inside_or_parent_of_any,
37
35
        pathjoin,
38
36
        pumpfile,
39
 
        pump_string_file,
40
 
        canonical_relpath,
41
37
        )
42
38
from bzrlib.tests import (
43
 
        adapt_tests,
44
 
        Feature,
45
39
        probe_unicode_in_user_encoding,
46
 
        split_suite_by_re,
47
40
        StringIOWrapper,
48
41
        SymlinkFeature,
49
 
        CaseInsCasePresFilenameFeature,
50
42
        TestCase,
51
43
        TestCaseInTempDir,
52
 
        TestScenarioApplier,
53
44
        TestSkipped,
54
45
        )
55
46
from bzrlib.tests.file_utils import (
56
47
    FakeReadFile,
57
48
    )
58
 
from bzrlib.tests.test__walkdirs_win32 import Win32ReadDirFeature
59
 
 
60
 
 
61
 
class _UTF8DirReaderFeature(Feature):
62
 
 
63
 
    def _probe(self):
64
 
        try:
65
 
            from bzrlib import _readdir_pyx
66
 
            self.reader = _readdir_pyx.UTF8DirReader
67
 
            return True
68
 
        except ImportError:
69
 
            return False
70
 
 
71
 
    def feature_name(self):
72
 
        return 'bzrlib._readdir_pyx'
73
 
 
74
 
UTF8DirReaderFeature = _UTF8DirReaderFeature()
75
 
 
 
49
from cStringIO import StringIO
76
50
 
77
51
class TestOSUtils(TestCaseInTempDir):
78
52
 
293
267
    def test_format_date(self):
294
268
        self.assertRaises(errors.UnsupportedTimezoneFormat,
295
269
            osutils.format_date, 0, timezone='foo')
296
 
        self.assertIsInstance(osutils.format_date(0), str)
297
 
        self.assertIsInstance(osutils.format_local_date(0), unicode)
298
 
        # Testing for the actual value of the local weekday without
299
 
        # duplicating the code from format_date is difficult.
300
 
        # Instead blackbox.test_locale should check for localized
301
 
        # dates once they do occur in output strings.
302
270
 
303
271
    def test_dereference_path(self):
304
272
        self.requireFeature(SymlinkFeature)
358
326
        osutils.host_os_dereferences_symlinks()
359
327
 
360
328
 
361
 
class TestCanonicalRelPath(TestCaseInTempDir):
362
 
 
363
 
    _test_needs_features = [CaseInsCasePresFilenameFeature]
364
 
 
365
 
    def test_canonical_relpath_simple(self):
366
 
        f = file('MixedCaseName', 'w')
367
 
        f.close()
368
 
        self.failUnlessEqual(
369
 
            canonical_relpath(self.test_base_dir, 'mixedcasename'),
370
 
            'work/MixedCaseName')
371
 
 
372
 
    def test_canonical_relpath_missing_tail(self):
373
 
        os.mkdir('MixedCaseParent')
374
 
        self.failUnlessEqual(
375
 
            canonical_relpath(self.test_base_dir, 'mixedcaseparent/nochild'),
376
 
            'work/MixedCaseParent/nochild')
377
 
 
378
 
 
379
329
class TestPumpFile(TestCase):
380
330
    """Test pumpfile method."""
381
331
    def setUp(self):
486
436
            message = "Data not equal.  Expected %d bytes, received %d."
487
437
            self.fail(message % (len(response_data), self.test_data_len))
488
438
 
489
 
    def test_report_activity(self):
490
 
        activity = []
491
 
        def log_activity(length, direction):
492
 
            activity.append((length, direction))
493
 
        from_file = StringIO(self.test_data)
494
 
        to_file = StringIO()
495
 
        pumpfile(from_file, to_file, buff_size=500,
496
 
                 report_activity=log_activity, direction='read')
497
 
        self.assertEqual([(500, 'read'), (500, 'read'), (500, 'read'),
498
 
                          (36, 'read')], activity)
499
 
 
500
 
        from_file = StringIO(self.test_data)
501
 
        to_file = StringIO()
502
 
        del activity[:]
503
 
        pumpfile(from_file, to_file, buff_size=500,
504
 
                 report_activity=log_activity, direction='write')
505
 
        self.assertEqual([(500, 'write'), (500, 'write'), (500, 'write'),
506
 
                          (36, 'write')], activity)
507
 
 
508
 
        # And with a limited amount of data
509
 
        from_file = StringIO(self.test_data)
510
 
        to_file = StringIO()
511
 
        del activity[:]
512
 
        pumpfile(from_file, to_file, buff_size=500, read_length=1028,
513
 
                 report_activity=log_activity, direction='read')
514
 
        self.assertEqual([(500, 'read'), (500, 'read'), (28, 'read')], activity)
515
 
 
516
 
 
517
 
 
518
 
class TestPumpStringFile(TestCase):
519
 
 
520
 
    def test_empty(self):
521
 
        output = StringIO()
522
 
        pump_string_file("", output)
523
 
        self.assertEqual("", output.getvalue())
524
 
 
525
 
    def test_more_than_segment_size(self):
526
 
        output = StringIO()
527
 
        pump_string_file("123456789", output, 2)
528
 
        self.assertEqual("123456789", output.getvalue())
529
 
 
530
 
    def test_segment_size(self):
531
 
        output = StringIO()
532
 
        pump_string_file("12", output, 2)
533
 
        self.assertEqual("12", output.getvalue())
534
 
 
535
 
    def test_segment_size_multiple(self):
536
 
        output = StringIO()
537
 
        pump_string_file("1234", output, 2)
538
 
        self.assertEqual("1234", output.getvalue())
539
 
 
540
 
 
541
439
class TestSafeUnicode(TestCase):
542
440
 
543
441
    def test_from_ascii_string(self):
804
702
        self.assertEndsWith(osutils._mac_getcwd(), u'B\xe5gfors')
805
703
 
806
704
 
807
 
class TestChunksToLines(TestCase):
808
 
 
809
 
    def test_smoketest(self):
810
 
        self.assertEqual(['foo\n', 'bar\n', 'baz\n'],
811
 
                         osutils.chunks_to_lines(['foo\nbar', '\nbaz\n']))
812
 
        self.assertEqual(['foo\n', 'bar\n', 'baz\n'],
813
 
                         osutils.chunks_to_lines(['foo\n', 'bar\n', 'baz\n']))
814
 
 
815
 
    def test_osutils_binding(self):
816
 
        from bzrlib.tests import test__chunks_to_lines
817
 
        if test__chunks_to_lines.CompiledChunksToLinesFeature.available():
818
 
            from bzrlib._chunks_to_lines_pyx import chunks_to_lines
819
 
        else:
820
 
            from bzrlib._chunks_to_lines_py import chunks_to_lines
821
 
        self.assertIs(chunks_to_lines, osutils.chunks_to_lines)
822
 
 
823
 
 
824
705
class TestSplitLines(TestCase):
825
706
 
826
707
    def test_split_unicode(self):
937
818
                new_dirblock.append((info[0], info[1], info[2], info[4]))
938
819
            dirblock[:] = new_dirblock
939
820
 
940
 
    def _save_platform_info(self):
941
 
        cur_winver = win32utils.winver
942
 
        cur_fs_enc = osutils._fs_enc
943
 
        cur_dir_reader = osutils._selected_dir_reader
944
 
        def restore():
945
 
            win32utils.winver = cur_winver
946
 
            osutils._fs_enc = cur_fs_enc
947
 
            osutils._selected_dir_reader = cur_dir_reader
948
 
        self.addCleanup(restore)
949
 
 
950
 
    def assertReadFSDirIs(self, expected):
951
 
        """Assert the right implementation for _walkdirs_utf8 is chosen."""
952
 
        # Force it to redetect
953
 
        osutils._selected_dir_reader = None
954
 
        # Nothing to list, but should still trigger the selection logic
955
 
        self.assertEqual([(('', '.'), [])], list(osutils._walkdirs_utf8('.')))
956
 
        self.assertIsInstance(osutils._selected_dir_reader, expected)
957
 
 
958
 
    def test_force_walkdirs_utf8_fs_utf8(self):
959
 
        self.requireFeature(UTF8DirReaderFeature)
960
 
        self._save_platform_info()
961
 
        win32utils.winver = None # Avoid the win32 detection code
962
 
        osutils._fs_enc = 'UTF-8'
963
 
        self.assertReadFSDirIs(UTF8DirReaderFeature.reader)
964
 
 
965
 
    def test_force_walkdirs_utf8_fs_ascii(self):
966
 
        self.requireFeature(UTF8DirReaderFeature)
967
 
        self._save_platform_info()
968
 
        win32utils.winver = None # Avoid the win32 detection code
969
 
        osutils._fs_enc = 'US-ASCII'
970
 
        self.assertReadFSDirIs(UTF8DirReaderFeature.reader)
971
 
 
972
 
    def test_force_walkdirs_utf8_fs_ANSI(self):
973
 
        self.requireFeature(UTF8DirReaderFeature)
974
 
        self._save_platform_info()
975
 
        win32utils.winver = None # Avoid the win32 detection code
976
 
        osutils._fs_enc = 'ANSI_X3.4-1968'
977
 
        self.assertReadFSDirIs(UTF8DirReaderFeature.reader)
978
 
 
979
 
    def test_force_walkdirs_utf8_fs_latin1(self):
980
 
        self._save_platform_info()
981
 
        win32utils.winver = None # Avoid the win32 detection code
982
 
        osutils._fs_enc = 'latin1'
983
 
        self.assertReadFSDirIs(osutils.UnicodeDirReader)
984
 
 
985
 
    def test_force_walkdirs_utf8_nt(self):
986
 
        # Disabled because the thunk of the whole walkdirs api is disabled.
987
 
        self.requireFeature(Win32ReadDirFeature)
988
 
        self._save_platform_info()
989
 
        win32utils.winver = 'Windows NT'
990
 
        from bzrlib._walkdirs_win32 import Win32ReadDir
991
 
        self.assertReadFSDirIs(Win32ReadDir)
992
 
 
993
 
    def test_force_walkdirs_utf8_98(self):
994
 
        self.requireFeature(Win32ReadDirFeature)
995
 
        self._save_platform_info()
996
 
        win32utils.winver = 'Windows 98'
997
 
        self.assertReadFSDirIs(osutils.UnicodeDirReader)
998
 
 
999
821
    def test_unicode_walkdirs(self):
1000
822
        """Walkdirs should always return unicode paths."""
1001
823
        name0 = u'0file-\xb6'
1103
925
            result.append((dirdetail, new_dirblock))
1104
926
        self.assertEqual(expected_dirblocks, result)
1105
927
 
1106
 
    def test__walkdirs_utf8_with_unicode_fs(self):
1107
 
        """UnicodeDirReader should be a safe fallback everywhere
 
928
    def test_unicode__walkdirs_unicode_to_utf8(self):
 
929
        """walkdirs_unicode_to_utf8 should be a safe fallback everywhere
1108
930
 
1109
931
        The abspath portion should be in unicode
1110
932
        """
1111
 
        # Use the unicode reader. TODO: split into driver-and-driven unit
1112
 
        # tests.
1113
 
        self._save_platform_info()
1114
 
        osutils._selected_dir_reader = osutils.UnicodeDirReader()
1115
933
        name0u = u'0file-\xb6'
1116
934
        name1u = u'1dir-\u062c\u0648'
1117
935
        name2u = u'2file-\u0633'
1152
970
                 ]
1153
971
                ),
1154
972
            ]
1155
 
        result = list(osutils._walkdirs_utf8('.'))
1156
 
        self._filter_out_stat(result)
1157
 
        self.assertEqual(expected_dirblocks, result)
1158
 
 
1159
 
    def test__walkdirs_utf8_win32readdir(self):
1160
 
        self.requireFeature(Win32ReadDirFeature)
1161
 
        self.requireFeature(tests.UnicodeFilenameFeature)
1162
 
        from bzrlib._walkdirs_win32 import Win32ReadDir
1163
 
        self._save_platform_info()
1164
 
        osutils._selected_dir_reader = Win32ReadDir()
1165
 
        name0u = u'0file-\xb6'
1166
 
        name1u = u'1dir-\u062c\u0648'
1167
 
        name2u = u'2file-\u0633'
1168
 
        tree = [
1169
 
            name0u,
1170
 
            name1u + '/',
1171
 
            name1u + '/' + name0u,
1172
 
            name1u + '/' + name1u + '/',
1173
 
            name2u,
1174
 
            ]
1175
 
        self.build_tree(tree)
1176
 
        name0 = name0u.encode('utf8')
1177
 
        name1 = name1u.encode('utf8')
1178
 
        name2 = name2u.encode('utf8')
1179
 
 
1180
 
        # All of the abspaths should be in unicode, all of the relative paths
1181
 
        # should be in utf8
1182
 
        expected_dirblocks = [
1183
 
                (('', '.'),
1184
 
                 [(name0, name0, 'file', './' + name0u),
1185
 
                  (name1, name1, 'directory', './' + name1u),
1186
 
                  (name2, name2, 'file', './' + name2u),
1187
 
                 ]
1188
 
                ),
1189
 
                ((name1, './' + name1u),
1190
 
                 [(name1 + '/' + name0, name0, 'file', './' + name1u
1191
 
                                                        + '/' + name0u),
1192
 
                  (name1 + '/' + name1, name1, 'directory', './' + name1u
1193
 
                                                            + '/' + name1u),
1194
 
                 ]
1195
 
                ),
1196
 
                ((name1 + '/' + name1, './' + name1u + '/' + name1u),
1197
 
                 [
1198
 
                 ]
1199
 
                ),
1200
 
            ]
1201
 
        result = list(osutils._walkdirs_utf8(u'.'))
1202
 
        self._filter_out_stat(result)
1203
 
        self.assertEqual(expected_dirblocks, result)
1204
 
 
1205
 
    def assertStatIsCorrect(self, path, win32stat):
1206
 
        os_stat = os.stat(path)
1207
 
        self.assertEqual(os_stat.st_size, win32stat.st_size)
1208
 
        self.assertAlmostEqual(os_stat.st_mtime, win32stat.st_mtime, places=4)
1209
 
        self.assertAlmostEqual(os_stat.st_ctime, win32stat.st_ctime, places=4)
1210
 
        self.assertAlmostEqual(os_stat.st_atime, win32stat.st_atime, places=4)
1211
 
        self.assertEqual(os_stat.st_dev, win32stat.st_dev)
1212
 
        self.assertEqual(os_stat.st_ino, win32stat.st_ino)
1213
 
        self.assertEqual(os_stat.st_mode, win32stat.st_mode)
1214
 
 
1215
 
    def test__walkdirs_utf_win32_find_file_stat_file(self):
1216
 
        """make sure our Stat values are valid"""
1217
 
        self.requireFeature(Win32ReadDirFeature)
1218
 
        self.requireFeature(tests.UnicodeFilenameFeature)
1219
 
        from bzrlib._walkdirs_win32 import Win32ReadDir
1220
 
        name0u = u'0file-\xb6'
1221
 
        name0 = name0u.encode('utf8')
1222
 
        self.build_tree([name0u])
1223
 
        # I hate to sleep() here, but I'm trying to make the ctime different
1224
 
        # from the mtime
1225
 
        time.sleep(2)
1226
 
        f = open(name0u, 'ab')
1227
 
        try:
1228
 
            f.write('just a small update')
1229
 
        finally:
1230
 
            f.close()
1231
 
 
1232
 
        result = Win32ReadDir().read_dir('', u'.')
1233
 
        entry = result[0]
1234
 
        self.assertEqual((name0, name0, 'file'), entry[:3])
1235
 
        self.assertEqual(u'./' + name0u, entry[4])
1236
 
        self.assertStatIsCorrect(entry[4], entry[3])
1237
 
        self.assertNotEqual(entry[3].st_mtime, entry[3].st_ctime)
1238
 
 
1239
 
    def test__walkdirs_utf_win32_find_file_stat_directory(self):
1240
 
        """make sure our Stat values are valid"""
1241
 
        self.requireFeature(Win32ReadDirFeature)
1242
 
        self.requireFeature(tests.UnicodeFilenameFeature)
1243
 
        from bzrlib._walkdirs_win32 import Win32ReadDir
1244
 
        name0u = u'0dir-\u062c\u0648'
1245
 
        name0 = name0u.encode('utf8')
1246
 
        self.build_tree([name0u + '/'])
1247
 
 
1248
 
        result = Win32ReadDir().read_dir('', u'.')
1249
 
        entry = result[0]
1250
 
        self.assertEqual((name0, name0, 'directory'), entry[:3])
1251
 
        self.assertEqual(u'./' + name0u, entry[4])
1252
 
        self.assertStatIsCorrect(entry[4], entry[3])
 
973
        result = list(osutils._walkdirs_unicode_to_utf8('.'))
 
974
        self._filter_out_stat(result)
 
975
        self.assertEqual(expected_dirblocks, result)
1253
976
 
1254
977
    def assertPathCompare(self, path_less, path_greater):
1255
978
        """check that path_less and path_greater compare correctly."""
1421
1144
        uni_val, env_val = probe_unicode_in_user_encoding()
1422
1145
        if uni_val is None:
1423
1146
            raise TestSkipped('Cannot find a unicode character that works in'
1424
 
                              ' encoding %s' % (osutils.get_user_encoding(),))
 
1147
                              ' encoding %s' % (bzrlib.user_encoding,))
1425
1148
 
1426
1149
        old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', uni_val)
1427
1150
        self.assertEqual(env_val, os.environ.get('BZR_TEST_ENV_VAR'))
1471
1194
        self.assertEqual(expected_sha, osutils.sha_file_by_name('foo'))
1472
1195
 
1473
1196
 
 
1197
_debug_text = \
 
1198
r'''# Copyright (C) 2005, 2006 Canonical Ltd
 
1199
#
 
1200
# This program is free software; you can redistribute it and/or modify
 
1201
# it under the terms of the GNU General Public License as published by
 
1202
# the Free Software Foundation; either version 2 of the License, or
 
1203
# (at your option) any later version.
 
1204
#
 
1205
# This program is distributed in the hope that it will be useful,
 
1206
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
1207
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
1208
# GNU General Public License for more details.
 
1209
#
 
1210
# You should have received a copy of the GNU General Public License
 
1211
# along with this program; if not, write to the Free Software
 
1212
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
1213
 
 
1214
 
 
1215
# NOTE: If update these, please also update the help for global-options in
 
1216
#       bzrlib/help_topics/__init__.py
 
1217
 
 
1218
debug_flags = set()
 
1219
"""Set of flags that enable different debug behaviour.
 
1220
 
 
1221
These are set with eg ``-Dlock`` on the bzr command line.
 
1222
 
 
1223
Options include:
 
1224
 
 
1225
 * auth - show authentication sections used
 
1226
 * error - show stack traces for all top level exceptions
 
1227
 * evil - capture call sites that do expensive or badly-scaling operations.
 
1228
 * fetch - trace history copying between repositories
 
1229
 * graph - trace graph traversal information
 
1230
 * hashcache - log every time a working file is read to determine its hash
 
1231
 * hooks - trace hook execution
 
1232
 * hpss - trace smart protocol requests and responses
 
1233
 * http - trace http connections, requests and responses
 
1234
 * index - trace major index operations
 
1235
 * knit - trace knit operations
 
1236
 * lock - trace when lockdir locks are taken or released
 
1237
 * merge - emit information for debugging merges
 
1238
 * pack - emit information about pack operations
 
1239
 
 
1240
"""
 
1241
'''
 
1242
 
 
1243
 
1474
1244
class TestResourceLoading(TestCaseInTempDir):
1475
1245
 
1476
1246
    def test_resource_string(self):
1477
1247
        # test resource in bzrlib
1478
1248
        text = osutils.resource_string('bzrlib', 'debug.py')
1479
 
        self.assertContainsRe(text, "debug_flags = set()")
 
1249
        self.assertEquals(_debug_text, text)
1480
1250
        # test resource under bzrlib
1481
1251
        text = osutils.resource_string('bzrlib.ui', 'text.py')
1482
1252
        self.assertContainsRe(text, "class TextUIFactory")