~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_osutils.py

  • Committer: Andrew Bennetts
  • Date: 2010-10-08 08:15:14 UTC
  • mto: This revision was merged to the branch mainline in revision 5498.
  • Revision ID: andrew.bennetts@canonical.com-20101008081514-dviqzrdfwyzsqbz2
Split NEWS into per-release doc/en/release-notes/bzr-*.txt

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2016 Canonical Ltd
 
1
# Copyright (C) 2005-2010 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
20
20
import errno
21
21
import os
22
22
import re
23
 
import select
24
23
import socket
25
24
import sys
26
 
import tempfile
27
25
import time
28
26
 
29
27
from bzrlib import (
40
38
    file_utils,
41
39
    test__walkdirs_win32,
42
40
    )
43
 
from bzrlib.tests.scenarios import load_tests_apply_scenarios
44
 
 
45
 
 
46
 
class _UTF8DirReaderFeature(features.Feature):
 
41
 
 
42
 
 
43
class _UTF8DirReaderFeature(tests.Feature):
47
44
 
48
45
    def _probe(self):
49
46
        try:
56
53
    def feature_name(self):
57
54
        return 'bzrlib._readdir_pyx'
58
55
 
59
 
UTF8DirReaderFeature = features.ModuleAvailableFeature('bzrlib._readdir_pyx')
 
56
UTF8DirReaderFeature = _UTF8DirReaderFeature()
60
57
 
61
 
term_ios_feature = features.ModuleAvailableFeature('termios')
 
58
term_ios_feature = tests.ModuleAvailableFeature('termios')
62
59
 
63
60
 
64
61
def _already_unicode(s):
99
96
    return scenarios
100
97
 
101
98
 
102
 
load_tests = load_tests_apply_scenarios
 
99
def load_tests(basic_tests, module, loader):
 
100
    suite = loader.suiteClass()
 
101
    dir_reader_tests, remaining_tests = tests.split_suite_by_condition(
 
102
        basic_tests, tests.condition_isinstance(TestDirReader))
 
103
    tests.multiply_tests(dir_reader_tests, dir_reader_scenarios(), suite)
 
104
    suite.addTest(remaining_tests)
 
105
    return suite
103
106
 
104
107
 
105
108
class TestContainsWhitespace(tests.TestCase):
106
109
 
107
110
    def test_contains_whitespace(self):
108
 
        self.assertTrue(osutils.contains_whitespace(u' '))
109
 
        self.assertTrue(osutils.contains_whitespace(u'hello there'))
110
 
        self.assertTrue(osutils.contains_whitespace(u'hellothere\n'))
111
 
        self.assertTrue(osutils.contains_whitespace(u'hello\nthere'))
112
 
        self.assertTrue(osutils.contains_whitespace(u'hello\rthere'))
113
 
        self.assertTrue(osutils.contains_whitespace(u'hello\tthere'))
 
111
        self.failUnless(osutils.contains_whitespace(u' '))
 
112
        self.failUnless(osutils.contains_whitespace(u'hello there'))
 
113
        self.failUnless(osutils.contains_whitespace(u'hellothere\n'))
 
114
        self.failUnless(osutils.contains_whitespace(u'hello\nthere'))
 
115
        self.failUnless(osutils.contains_whitespace(u'hello\rthere'))
 
116
        self.failUnless(osutils.contains_whitespace(u'hello\tthere'))
114
117
 
115
118
        # \xa0 is "Non-breaking-space" which on some python locales thinks it
116
119
        # is whitespace, but we do not.
117
 
        self.assertFalse(osutils.contains_whitespace(u''))
118
 
        self.assertFalse(osutils.contains_whitespace(u'hellothere'))
119
 
        self.assertFalse(osutils.contains_whitespace(u'hello\xa0there'))
 
120
        self.failIf(osutils.contains_whitespace(u''))
 
121
        self.failIf(osutils.contains_whitespace(u'hellothere'))
 
122
        self.failIf(osutils.contains_whitespace(u'hello\xa0there'))
120
123
 
121
124
 
122
125
class TestRename(tests.TestCaseInTempDir):
136
139
        # This should work everywhere
137
140
        self.create_file('a', 'something in a\n')
138
141
        self._fancy_rename('a', 'b')
139
 
        self.assertPathDoesNotExist('a')
140
 
        self.assertPathExists('b')
 
142
        self.failIfExists('a')
 
143
        self.failUnlessExists('b')
141
144
        self.check_file_contents('b', 'something in a\n')
142
145
 
143
146
        self.create_file('a', 'new something in a\n')
150
153
        self.create_file('target', 'data in target\n')
151
154
        self.assertRaises((IOError, OSError), self._fancy_rename,
152
155
                          'missingsource', 'target')
153
 
        self.assertPathExists('target')
 
156
        self.failUnlessExists('target')
154
157
        self.check_file_contents('target', 'data in target\n')
155
158
 
156
159
    def test_fancy_rename_fails_if_source_and_target_missing(self):
161
164
        # Rename should be semi-atomic on all platforms
162
165
        self.create_file('a', 'something in a\n')
163
166
        osutils.rename('a', 'b')
164
 
        self.assertPathDoesNotExist('a')
165
 
        self.assertPathExists('b')
 
167
        self.failIfExists('a')
 
168
        self.failUnlessExists('b')
166
169
        self.check_file_contents('b', 'something in a\n')
167
170
 
168
171
        self.create_file('a', 'new something in a\n')
180
183
        # we can't use failUnlessExists on case-insensitive filesystem
181
184
        # so try to check shape of the tree
182
185
        shape = sorted(os.listdir('.'))
183
 
        self.assertEqual(['A', 'B'], shape)
184
 
 
185
 
    def test_rename_exception(self):
186
 
        try:
187
 
            osutils.rename('nonexistent_path', 'different_nonexistent_path')
188
 
        except OSError, e:
189
 
            self.assertEqual(e.old_filename, 'nonexistent_path')
190
 
            self.assertEqual(e.new_filename, 'different_nonexistent_path')
191
 
            self.assertTrue('nonexistent_path' in e.strerror)
192
 
            self.assertTrue('different_nonexistent_path' in e.strerror)
 
186
        self.assertEquals(['A', 'B'], shape)
193
187
 
194
188
 
195
189
class TestRandChars(tests.TestCase):
222
216
                         (['src'], SRC_FOO_C),
223
217
                         (['src'], 'src'),
224
218
                         ]:
225
 
            self.assertTrue(osutils.is_inside_any(dirs, fn))
 
219
            self.assert_(osutils.is_inside_any(dirs, fn))
226
220
        for dirs, fn in [(['src'], 'srccontrol'),
227
221
                         (['src'], 'srccontrol/foo')]:
228
222
            self.assertFalse(osutils.is_inside_any(dirs, fn))
234
228
                         (['src/bar.c', 'bla/foo.c'], 'src'),
235
229
                         (['src'], 'src'),
236
230
                         ]:
237
 
            self.assertTrue(osutils.is_inside_or_parent_of_any(dirs, fn))
 
231
            self.assert_(osutils.is_inside_or_parent_of_any(dirs, fn))
238
232
 
239
233
        for dirs, fn in [(['src'], 'srccontrol'),
240
234
                         (['srccontrol/foo.c'], 'src'),
242
236
            self.assertFalse(osutils.is_inside_or_parent_of_any(dirs, fn))
243
237
 
244
238
 
245
 
class TestLstat(tests.TestCaseInTempDir):
246
 
 
247
 
    def test_lstat_matches_fstat(self):
248
 
        # On Windows, lstat and fstat don't always agree, primarily in the
249
 
        # 'st_ino' and 'st_dev' fields. So we force them to be '0' in our
250
 
        # custom implementation.
251
 
        if sys.platform == 'win32':
252
 
            # We only have special lstat/fstat if we have the extension.
253
 
            # Without it, we may end up re-reading content when we don't have
254
 
            # to, but otherwise it doesn't effect correctness.
255
 
            self.requireFeature(test__walkdirs_win32.win32_readdir_feature)
256
 
        f = open('test-file.txt', 'wb')
257
 
        self.addCleanup(f.close)
258
 
        f.write('some content\n')
259
 
        f.flush()
260
 
        self.assertEqualStat(osutils.fstat(f.fileno()),
261
 
                             osutils.lstat('test-file.txt'))
262
 
 
263
 
 
264
239
class TestRmTree(tests.TestCaseInTempDir):
265
240
 
266
241
    def test_rmtree(self):
278
253
 
279
254
        osutils.rmtree('dir')
280
255
 
281
 
        self.assertPathDoesNotExist('dir/file')
282
 
        self.assertPathDoesNotExist('dir')
 
256
        self.failIfExists('dir/file')
 
257
        self.failIfExists('dir')
283
258
 
284
259
 
285
260
class TestDeleteAny(tests.TestCaseInTempDir):
298
273
 
299
274
    def test_file_kind(self):
300
275
        self.build_tree(['file', 'dir/'])
301
 
        self.assertEqual('file', osutils.file_kind('file'))
302
 
        self.assertEqual('directory', osutils.file_kind('dir/'))
 
276
        self.assertEquals('file', osutils.file_kind('file'))
 
277
        self.assertEquals('directory', osutils.file_kind('dir/'))
303
278
        if osutils.has_symlinks():
304
279
            os.symlink('symlink', 'symlink')
305
 
            self.assertEqual('symlink', osutils.file_kind('symlink'))
 
280
            self.assertEquals('symlink', osutils.file_kind('symlink'))
306
281
 
307
282
        # TODO: jam 20060529 Test a block device
308
283
        try:
311
286
            if e.errno not in (errno.ENOENT,):
312
287
                raise
313
288
        else:
314
 
            self.assertEqual('chardev', osutils.file_kind('/dev/null'))
 
289
            self.assertEquals('chardev', osutils.file_kind('/dev/null'))
315
290
 
316
291
        mkfifo = getattr(os, 'mkfifo', None)
317
292
        if mkfifo:
318
293
            mkfifo('fifo')
319
294
            try:
320
 
                self.assertEqual('fifo', osutils.file_kind('fifo'))
 
295
                self.assertEquals('fifo', osutils.file_kind('fifo'))
321
296
            finally:
322
297
                os.remove('fifo')
323
298
 
326
301
            s = socket.socket(AF_UNIX)
327
302
            s.bind('socket')
328
303
            try:
329
 
                self.assertEqual('socket', osutils.file_kind('socket'))
 
304
                self.assertEquals('socket', osutils.file_kind('socket'))
330
305
            finally:
331
306
                os.remove('socket')
332
307
 
437
412
        self.assertTrue(-eighteen_hours < offset < eighteen_hours)
438
413
 
439
414
 
440
 
class TestFdatasync(tests.TestCaseInTempDir):
441
 
 
442
 
    def do_fdatasync(self):
443
 
        f = tempfile.NamedTemporaryFile()
444
 
        osutils.fdatasync(f.fileno())
445
 
        f.close()
446
 
 
447
 
    @staticmethod
448
 
    def raise_eopnotsupp(*args, **kwargs):
449
 
        raise IOError(errno.EOPNOTSUPP, os.strerror(errno.EOPNOTSUPP))
450
 
 
451
 
    @staticmethod
452
 
    def raise_enotsup(*args, **kwargs):
453
 
        raise IOError(errno.ENOTSUP, os.strerror(errno.ENOTSUP))
454
 
 
455
 
    def test_fdatasync_handles_system_function(self):
456
 
        self.overrideAttr(os, "fdatasync")
457
 
        self.do_fdatasync()
458
 
 
459
 
    def test_fdatasync_handles_no_fdatasync_no_fsync(self):
460
 
        self.overrideAttr(os, "fdatasync")
461
 
        self.overrideAttr(os, "fsync")
462
 
        self.do_fdatasync()
463
 
 
464
 
    def test_fdatasync_handles_no_EOPNOTSUPP(self):
465
 
        self.overrideAttr(errno, "EOPNOTSUPP")
466
 
        self.do_fdatasync()
467
 
 
468
 
    def test_fdatasync_catches_ENOTSUP(self):
469
 
        enotsup = getattr(errno, "ENOTSUP", None)
470
 
        if enotsup is None:
471
 
            raise tests.TestNotApplicable("No ENOTSUP on this platform")
472
 
        self.overrideAttr(os, "fdatasync", self.raise_enotsup)
473
 
        self.do_fdatasync()
474
 
 
475
 
    def test_fdatasync_catches_EOPNOTSUPP(self):
476
 
        enotsup = getattr(errno, "EOPNOTSUPP", None)
477
 
        if enotsup is None:
478
 
            raise tests.TestNotApplicable("No EOPNOTSUPP on this platform")
479
 
        self.overrideAttr(os, "fdatasync", self.raise_eopnotsupp)
480
 
        self.do_fdatasync()
481
 
 
482
 
 
483
415
class TestLinks(tests.TestCaseInTempDir):
484
416
 
485
417
    def test_dereference_path(self):
486
 
        self.requireFeature(features.SymlinkFeature)
 
418
        self.requireFeature(tests.SymlinkFeature)
487
419
        cwd = osutils.realpath('.')
488
420
        os.mkdir('bar')
489
421
        bar_path = osutils.pathjoin(cwd, 'bar')
536
468
 
537
469
class TestCanonicalRelPath(tests.TestCaseInTempDir):
538
470
 
539
 
    _test_needs_features = [features.CaseInsCasePresFilenameFeature]
 
471
    _test_needs_features = [tests.CaseInsCasePresFilenameFeature]
540
472
 
541
473
    def test_canonical_relpath_simple(self):
542
474
        f = file('MixedCaseName', 'w')
543
475
        f.close()
544
476
        actual = osutils.canonical_relpath(self.test_base_dir, 'mixedcasename')
545
 
        self.assertEqual('work/MixedCaseName', actual)
 
477
        self.failUnlessEqual('work/MixedCaseName', actual)
546
478
 
547
479
    def test_canonical_relpath_missing_tail(self):
548
480
        os.mkdir('MixedCaseParent')
549
481
        actual = osutils.canonical_relpath(self.test_base_dir,
550
482
                                           'mixedcaseparent/nochild')
551
 
        self.assertEqual('work/MixedCaseParent/nochild', actual)
 
483
        self.failUnlessEqual('work/MixedCaseParent/nochild', actual)
552
484
 
553
485
 
554
486
class Test_CICPCanonicalRelpath(tests.TestCaseWithTransport):
598
530
    """Test pumpfile method."""
599
531
 
600
532
    def setUp(self):
601
 
        super(TestPumpFile, self).setUp()
 
533
        tests.TestCase.setUp(self)
602
534
        # create a test datablock
603
535
        self.block_size = 512
604
536
        pattern = '0123456789ABCDEF'
872
804
        self.assertEqual(None, osutils.safe_file_id(None))
873
805
 
874
806
 
875
 
class TestSendAll(tests.TestCase):
876
 
 
877
 
    def test_send_with_disconnected_socket(self):
878
 
        class DisconnectedSocket(object):
879
 
            def __init__(self, err):
880
 
                self.err = err
881
 
            def send(self, content):
882
 
                raise self.err
883
 
            def close(self):
884
 
                pass
885
 
        # All of these should be treated as ConnectionReset
886
 
        errs = []
887
 
        for err_cls in (IOError, socket.error):
888
 
            for errnum in osutils._end_of_stream_errors:
889
 
                errs.append(err_cls(errnum))
890
 
        for err in errs:
891
 
            sock = DisconnectedSocket(err)
892
 
            self.assertRaises(errors.ConnectionReset,
893
 
                osutils.send_all, sock, 'some more content')
894
 
 
895
 
    def test_send_with_no_progress(self):
896
 
        # See https://bugs.launchpad.net/bzr/+bug/1047309
897
 
        # It seems that paramiko can get into a state where it doesn't error,
898
 
        # but it returns 0 bytes sent for requests over and over again.
899
 
        class NoSendingSocket(object):
900
 
            def __init__(self):
901
 
                self.call_count = 0
902
 
            def send(self, bytes):
903
 
                self.call_count += 1
904
 
                if self.call_count > 100:
905
 
                    # Prevent the test suite from hanging
906
 
                    raise RuntimeError('too many calls')
907
 
                return 0
908
 
        sock = NoSendingSocket()
909
 
        self.assertRaises(errors.ConnectionReset,
910
 
                          osutils.send_all, sock, 'content')
911
 
        self.assertEqual(1, sock.call_count)
912
 
 
913
 
 
914
 
class TestPosixFuncs(tests.TestCase):
915
 
    """Test that the posix version of normpath returns an appropriate path
916
 
       when used with 2 leading slashes."""
917
 
 
918
 
    def test_normpath(self):
919
 
        self.assertEqual('/etc/shadow', osutils._posix_normpath('/etc/shadow'))
920
 
        self.assertEqual('/etc/shadow', osutils._posix_normpath('//etc/shadow'))
921
 
        self.assertEqual('/etc/shadow', osutils._posix_normpath('///etc/shadow'))
922
 
 
923
 
 
924
807
class TestWin32Funcs(tests.TestCase):
925
808
    """Test that _win32 versions of os utilities return appropriate paths."""
926
809
 
927
810
    def test_abspath(self):
928
 
        self.requireFeature(features.win32_feature)
929
811
        self.assertEqual('C:/foo', osutils._win32_abspath('C:\\foo'))
930
812
        self.assertEqual('C:/foo', osutils._win32_abspath('C:/foo'))
931
813
        self.assertEqual('//HOST/path', osutils._win32_abspath(r'\\HOST\path'))
944
826
                         osutils._win32_pathjoin('path/to', 'C:/foo'))
945
827
        self.assertEqual('path/to/foo',
946
828
                         osutils._win32_pathjoin('path/to/', 'foo'))
947
 
 
948
 
    def test_pathjoin_late_bugfix(self):
949
 
        if sys.version_info < (2, 7, 6):
950
 
            expected = '/foo'
951
 
        else:
952
 
            expected = 'C:/foo'
953
 
        self.assertEqual(expected,
 
829
        self.assertEqual('/foo',
954
830
                         osutils._win32_pathjoin('C:/path/to/', '/foo'))
955
 
        self.assertEqual(expected,
 
831
        self.assertEqual('/foo',
956
832
                         osutils._win32_pathjoin('C:\\path\\to\\', '\\foo'))
957
833
 
958
834
    def test_normpath(self):
978
854
        self.assertEqual('C:\\foo', osutils._win32_fixdrive('c:\\foo'))
979
855
 
980
856
    def test_win98_abspath(self):
981
 
        self.requireFeature(features.win32_feature)
982
857
        # absolute path
983
858
        self.assertEqual('C:/foo', osutils._win98_abspath('C:\\foo'))
984
859
        self.assertEqual('C:/foo', osutils._win98_abspath('C:/foo'))
999
874
    """Test win32 functions that create files."""
1000
875
 
1001
876
    def test_getcwd(self):
1002
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
877
        self.requireFeature(tests.UnicodeFilenameFeature)
1003
878
        os.mkdir(u'mu-\xb5')
1004
879
        os.chdir(u'mu-\xb5')
1005
880
        # TODO: jam 20060427 This will probably fail on Mac OSX because
1035
910
        b.close()
1036
911
 
1037
912
        osutils._win32_rename('b', 'a')
1038
 
        self.assertPathExists('a')
1039
 
        self.assertPathDoesNotExist('b')
 
913
        self.failUnlessExists('a')
 
914
        self.failIfExists('b')
1040
915
        self.assertFileEqual('baz\n', 'a')
1041
916
 
1042
917
    def test_rename_missing_file(self):
1095
970
    """Test mac special functions that require directories."""
1096
971
 
1097
972
    def test_getcwd(self):
1098
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
973
        self.requireFeature(tests.UnicodeFilenameFeature)
1099
974
        os.mkdir(u'B\xe5gfors')
1100
975
        os.chdir(u'B\xe5gfors')
1101
976
        self.assertEndsWith(osutils._mac_getcwd(), u'B\xe5gfors')
1102
977
 
1103
978
    def test_getcwd_nonnorm(self):
1104
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
979
        self.requireFeature(tests.UnicodeFilenameFeature)
1105
980
        # Test that _mac_getcwd() will normalize this path
1106
981
        os.mkdir(u'Ba\u030agfors')
1107
982
        os.chdir(u'Ba\u030agfors')
1205
1080
        # (It would be ok if it happened earlier but at the moment it
1206
1081
        # doesn't.)
1207
1082
        e = self.assertRaises(OSError, list, osutils._walkdirs_utf8("."))
1208
 
        self.assertEqual('./test-unreadable', e.filename)
1209
 
        self.assertEqual(errno.EACCES, e.errno)
 
1083
        self.assertEquals('./test-unreadable', e.filename)
 
1084
        self.assertEquals(errno.EACCES, e.errno)
1210
1085
        # Ensure the message contains the file name
1211
1086
        self.assertContainsRe(str(e), "\./test-unreadable")
1212
1087
 
1217
1092
        # are not using the filesystem's encoding
1218
1093
 
1219
1094
        # require a bytestring based filesystem
1220
 
        self.requireFeature(features.ByteStringNamedFilesystem)
 
1095
        self.requireFeature(tests.ByteStringNamedFilesystem)
1221
1096
 
1222
1097
        tree = [
1223
1098
            '.bzr',
1232
1107
 
1233
1108
        # rename the 1file to a latin-1 filename
1234
1109
        os.rename("./1file", "\xe8file")
1235
 
        if "\xe8file" not in os.listdir("."):
1236
 
            self.skip("Lack filesystem that preserves arbitrary bytes")
1237
1110
 
1238
1111
        self._save_platform_info()
1239
1112
        win32utils.winver = None # Avoid the win32 detection code
1317
1190
        self.requireFeature(UTF8DirReaderFeature)
1318
1191
        self._save_platform_info()
1319
1192
        win32utils.winver = None # Avoid the win32 detection code
1320
 
        osutils._fs_enc = 'utf-8'
1321
 
        self.assertDirReaderIs(
1322
 
            UTF8DirReaderFeature.module.UTF8DirReader)
 
1193
        osutils._fs_enc = 'UTF-8'
 
1194
        self.assertDirReaderIs(UTF8DirReaderFeature.reader)
1323
1195
 
1324
1196
    def test_force_walkdirs_utf8_fs_ascii(self):
1325
1197
        self.requireFeature(UTF8DirReaderFeature)
1326
1198
        self._save_platform_info()
1327
1199
        win32utils.winver = None # Avoid the win32 detection code
1328
 
        osutils._fs_enc = 'ascii'
1329
 
        self.assertDirReaderIs(
1330
 
            UTF8DirReaderFeature.module.UTF8DirReader)
 
1200
        osutils._fs_enc = 'US-ASCII'
 
1201
        self.assertDirReaderIs(UTF8DirReaderFeature.reader)
 
1202
 
 
1203
    def test_force_walkdirs_utf8_fs_ANSI(self):
 
1204
        self.requireFeature(UTF8DirReaderFeature)
 
1205
        self._save_platform_info()
 
1206
        win32utils.winver = None # Avoid the win32 detection code
 
1207
        osutils._fs_enc = 'ANSI_X3.4-1968'
 
1208
        self.assertDirReaderIs(UTF8DirReaderFeature.reader)
1331
1209
 
1332
1210
    def test_force_walkdirs_utf8_fs_latin1(self):
1333
1211
        self._save_platform_info()
1334
1212
        win32utils.winver = None # Avoid the win32 detection code
1335
 
        osutils._fs_enc = 'iso-8859-1'
 
1213
        osutils._fs_enc = 'latin1'
1336
1214
        self.assertDirReaderIs(osutils.UnicodeDirReader)
1337
1215
 
1338
1216
    def test_force_walkdirs_utf8_nt(self):
1351
1229
 
1352
1230
    def test_unicode_walkdirs(self):
1353
1231
        """Walkdirs should always return unicode paths."""
1354
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
1232
        self.requireFeature(tests.UnicodeFilenameFeature)
1355
1233
        name0 = u'0file-\xb6'
1356
1234
        name1 = u'1dir-\u062c\u0648'
1357
1235
        name2 = u'2file-\u0633'
1394
1272
 
1395
1273
        The abspath portion might be in unicode or utf-8
1396
1274
        """
1397
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
1275
        self.requireFeature(tests.UnicodeFilenameFeature)
1398
1276
        name0 = u'0file-\xb6'
1399
1277
        name1 = u'1dir-\u062c\u0648'
1400
1278
        name2 = u'2file-\u0633'
1455
1333
 
1456
1334
        The abspath portion should be in unicode
1457
1335
        """
1458
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
1336
        self.requireFeature(tests.UnicodeFilenameFeature)
1459
1337
        # Use the unicode reader. TODO: split into driver-and-driven unit
1460
1338
        # tests.
1461
1339
        self._save_platform_info()
1502
1380
 
1503
1381
    def test__walkdirs_utf8_win32readdir(self):
1504
1382
        self.requireFeature(test__walkdirs_win32.win32_readdir_feature)
1505
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
1383
        self.requireFeature(tests.UnicodeFilenameFeature)
1506
1384
        from bzrlib._walkdirs_win32 import Win32ReadDir
1507
1385
        self._save_platform_info()
1508
1386
        osutils._selected_dir_reader = Win32ReadDir()
1559
1437
    def test__walkdirs_utf_win32_find_file_stat_file(self):
1560
1438
        """make sure our Stat values are valid"""
1561
1439
        self.requireFeature(test__walkdirs_win32.win32_readdir_feature)
1562
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
1440
        self.requireFeature(tests.UnicodeFilenameFeature)
1563
1441
        from bzrlib._walkdirs_win32 import Win32ReadDir
1564
1442
        name0u = u'0file-\xb6'
1565
1443
        name0 = name0u.encode('utf8')
1583
1461
    def test__walkdirs_utf_win32_find_file_stat_directory(self):
1584
1462
        """make sure our Stat values are valid"""
1585
1463
        self.requireFeature(test__walkdirs_win32.win32_readdir_feature)
1586
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
1464
        self.requireFeature(tests.UnicodeFilenameFeature)
1587
1465
        from bzrlib._walkdirs_win32 import Win32ReadDir
1588
1466
        name0u = u'0dir-\u062c\u0648'
1589
1467
        name0 = name0u.encode('utf8')
1689
1567
        self.assertEqual(['c'], os.listdir('target/b'))
1690
1568
 
1691
1569
    def test_copy_tree_symlinks(self):
1692
 
        self.requireFeature(features.SymlinkFeature)
 
1570
        self.requireFeature(tests.SymlinkFeature)
1693
1571
        self.build_tree(['source/'])
1694
1572
        os.symlink('a/generic/path', 'source/lnk')
1695
1573
        osutils.copy_tree('source', 'target')
1720
1598
                          ('d', 'source/b', 'target/b'),
1721
1599
                          ('f', 'source/b/c', 'target/b/c'),
1722
1600
                         ], processed_files)
1723
 
        self.assertPathDoesNotExist('target')
 
1601
        self.failIfExists('target')
1724
1602
        if osutils.has_symlinks():
1725
1603
            self.assertEqual([('source/lnk', 'target/lnk')], processed_links)
1726
1604
 
1772
1650
        old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', None)
1773
1651
        self.assertEqual('foo', old)
1774
1652
        self.assertEqual(None, os.environ.get('BZR_TEST_ENV_VAR'))
1775
 
        self.assertFalse('BZR_TEST_ENV_VAR' in os.environ)
 
1653
        self.failIf('BZR_TEST_ENV_VAR' in os.environ)
1776
1654
 
1777
1655
 
1778
1656
class TestSizeShaFile(tests.TestCaseInTempDir):
1855
1733
 
1856
1734
class TestDirReader(tests.TestCaseInTempDir):
1857
1735
 
1858
 
    scenarios = dir_reader_scenarios()
1859
 
 
1860
1736
    # Set by load_tests
1861
1737
    _dir_reader_class = None
1862
1738
    _native_to_unicode = None
1863
1739
 
1864
1740
    def setUp(self):
1865
 
        super(TestDirReader, self).setUp()
 
1741
        tests.TestCaseInTempDir.setUp(self)
1866
1742
        self.overrideAttr(osutils,
1867
1743
                          '_selected_dir_reader', self._dir_reader_class())
1868
1744
 
1962
1838
        return filtered_dirblocks
1963
1839
 
1964
1840
    def test_walk_unicode_tree(self):
1965
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
1841
        self.requireFeature(tests.UnicodeFilenameFeature)
1966
1842
        tree, expected_dirblocks = self._get_unicode_tree()
1967
1843
        self.build_tree(tree)
1968
1844
        result = list(osutils._walkdirs_utf8('.'))
1969
1845
        self.assertEqual(expected_dirblocks, self._filter_out(result))
1970
1846
 
1971
1847
    def test_symlink(self):
1972
 
        self.requireFeature(features.SymlinkFeature)
1973
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
1848
        self.requireFeature(tests.SymlinkFeature)
 
1849
        self.requireFeature(tests.UnicodeFilenameFeature)
1974
1850
        target = u'target\N{Euro Sign}'
1975
1851
        link_name = u'l\N{Euro Sign}nk'
1976
1852
        os.symlink(target, link_name)
1994
1870
    But prior python versions failed to properly encode the passed unicode
1995
1871
    string.
1996
1872
    """
1997
 
    _test_needs_features = [features.SymlinkFeature, features.UnicodeFilenameFeature]
 
1873
    _test_needs_features = [tests.SymlinkFeature, tests.UnicodeFilenameFeature]
1998
1874
 
1999
1875
    def setUp(self):
2000
1876
        super(tests.TestCaseInTempDir, self).setUp()
2003
1879
        os.symlink(self.target, self.link)
2004
1880
 
2005
1881
    def test_os_readlink_link_encoding(self):
2006
 
        self.assertEqual(self.target,  os.readlink(self.link))
 
1882
        if sys.version_info < (2, 6):
 
1883
            self.assertRaises(UnicodeEncodeError, os.readlink, self.link)
 
1884
        else:
 
1885
            self.assertEquals(self.target,  os.readlink(self.link))
2007
1886
 
2008
1887
    def test_os_readlink_link_decoding(self):
2009
 
        self.assertEqual(self.target.encode(osutils._fs_enc),
 
1888
        self.assertEquals(self.target.encode(osutils._fs_enc),
2010
1889
                          os.readlink(self.link.encode(osutils._fs_enc)))
2011
1890
 
2012
1891
 
2021
1900
        self.assertIsInstance(concurrency, int)
2022
1901
 
2023
1902
    def test_local_concurrency_environment_variable(self):
2024
 
        self.overrideEnv('BZR_CONCURRENCY', '2')
 
1903
        os.environ['BZR_CONCURRENCY'] = '2'
2025
1904
        self.assertEqual(2, osutils.local_concurrency(use_cache=False))
2026
 
        self.overrideEnv('BZR_CONCURRENCY', '3')
 
1905
        os.environ['BZR_CONCURRENCY'] = '3'
2027
1906
        self.assertEqual(3, osutils.local_concurrency(use_cache=False))
2028
 
        self.overrideEnv('BZR_CONCURRENCY', 'foo')
 
1907
        os.environ['BZR_CONCURRENCY'] = 'foo'
2029
1908
        self.assertEqual(1, osutils.local_concurrency(use_cache=False))
2030
1909
 
2031
1910
    def test_option_concurrency(self):
2032
 
        self.overrideEnv('BZR_CONCURRENCY', '1')
 
1911
        os.environ['BZR_CONCURRENCY'] = '1'
2033
1912
        self.run_bzr('rocks --concurrency 42')
2034
 
        # Command line overrides environment variable
2035
 
        self.assertEqual('42', os.environ['BZR_CONCURRENCY'])
2036
 
        self.assertEqual(42, osutils.local_concurrency(use_cache=False))
 
1913
        # Command line overrides envrionment variable
 
1914
        self.assertEquals('42', os.environ['BZR_CONCURRENCY'])
 
1915
        self.assertEquals(42, osutils.local_concurrency(use_cache=False))
2037
1916
 
2038
1917
 
2039
1918
class TestFailedToLoadExtension(tests.TestCase):
2052
1931
    def test_failure_to_load(self):
2053
1932
        self._try_loading()
2054
1933
        self.assertLength(1, osutils._extension_load_failures)
2055
 
        self.assertEqual(osutils._extension_load_failures[0],
 
1934
        self.assertEquals(osutils._extension_load_failures[0],
2056
1935
            "No module named _fictional_extension_py")
2057
1936
 
2058
1937
    def test_report_extension_load_failures_no_warning(self):
2076
1955
class TestTerminalWidth(tests.TestCase):
2077
1956
 
2078
1957
    def setUp(self):
2079
 
        super(TestTerminalWidth, self).setUp()
 
1958
        tests.TestCase.setUp(self)
2080
1959
        self._orig_terminal_size_state = osutils._terminal_size_state
2081
1960
        self._orig_first_terminal_size = osutils._first_terminal_size
2082
1961
        self.addCleanup(self.restore_osutils_globals)
2107
1986
    def test_defaults_to_BZR_COLUMNS(self):
2108
1987
        # BZR_COLUMNS is set by the test framework
2109
1988
        self.assertNotEqual('12', os.environ['BZR_COLUMNS'])
2110
 
        self.overrideEnv('BZR_COLUMNS', '12')
 
1989
        os.environ['BZR_COLUMNS'] = '12'
2111
1990
        self.assertEqual(12, osutils.terminal_width())
2112
1991
 
2113
 
    def test_BZR_COLUMNS_0_no_limit(self):
2114
 
        self.overrideEnv('BZR_COLUMNS', '0')
2115
 
        self.assertEqual(None, osutils.terminal_width())
2116
 
 
2117
1992
    def test_falls_back_to_COLUMNS(self):
2118
 
        self.overrideEnv('BZR_COLUMNS', None)
 
1993
        del os.environ['BZR_COLUMNS']
2119
1994
        self.assertNotEqual('42', os.environ['COLUMNS'])
2120
1995
        self.set_fake_tty()
2121
 
        self.overrideEnv('COLUMNS', '42')
 
1996
        os.environ['COLUMNS'] = '42'
2122
1997
        self.assertEqual(42, osutils.terminal_width())
2123
1998
 
2124
1999
    def test_tty_default_without_columns(self):
2125
 
        self.overrideEnv('BZR_COLUMNS', None)
2126
 
        self.overrideEnv('COLUMNS', None)
 
2000
        del os.environ['BZR_COLUMNS']
 
2001
        del os.environ['COLUMNS']
2127
2002
 
2128
2003
        def terminal_size(w, h):
2129
2004
            return 42, 42
2136
2011
        self.assertEqual(42, osutils.terminal_width())
2137
2012
 
2138
2013
    def test_non_tty_default_without_columns(self):
2139
 
        self.overrideEnv('BZR_COLUMNS', None)
2140
 
        self.overrideEnv('COLUMNS', None)
 
2014
        del os.environ['BZR_COLUMNS']
 
2015
        del os.environ['COLUMNS']
2141
2016
        self.replace_stdout(None)
2142
2017
        self.assertEqual(None, osutils.terminal_width())
2143
2018
 
2153
2028
        else:
2154
2029
            self.overrideAttr(termios, 'TIOCGWINSZ')
2155
2030
            del termios.TIOCGWINSZ
2156
 
        self.overrideEnv('BZR_COLUMNS', None)
2157
 
        self.overrideEnv('COLUMNS', None)
 
2031
        del os.environ['BZR_COLUMNS']
 
2032
        del os.environ['COLUMNS']
2158
2033
        # Whatever the result is, if we don't raise an exception, it's ok.
2159
2034
        osutils.terminal_width()
2160
2035
 
2161
 
 
2162
2036
class TestCreationOps(tests.TestCaseInTempDir):
2163
2037
    _test_needs_features = [features.chown_feature]
2164
2038
 
2165
2039
    def setUp(self):
2166
 
        super(TestCreationOps, self).setUp()
 
2040
        tests.TestCaseInTempDir.setUp(self)
2167
2041
        self.overrideAttr(os, 'chown', self._dummy_chown)
2168
2042
 
2169
2043
        # params set by call to _dummy_chown
2179
2053
        osutils.copy_ownership_from_path('test_file', ownsrc)
2180
2054
 
2181
2055
        s = os.stat(ownsrc)
2182
 
        self.assertEqual(self.path, 'test_file')
2183
 
        self.assertEqual(self.uid, s.st_uid)
2184
 
        self.assertEqual(self.gid, s.st_gid)
 
2056
        self.assertEquals(self.path, 'test_file')
 
2057
        self.assertEquals(self.uid, s.st_uid)
 
2058
        self.assertEquals(self.gid, s.st_gid)
2185
2059
 
2186
2060
    def test_copy_ownership_nonesrc(self):
2187
2061
        """copy_ownership_from_path test with src=None."""
2190
2064
        osutils.copy_ownership_from_path('test_file')
2191
2065
 
2192
2066
        s = os.stat('..')
2193
 
        self.assertEqual(self.path, 'test_file')
2194
 
        self.assertEqual(self.uid, s.st_uid)
2195
 
        self.assertEqual(self.gid, s.st_gid)
2196
 
 
2197
 
 
2198
 
class TestPathFromEnviron(tests.TestCase):
2199
 
 
2200
 
    def test_is_unicode(self):
2201
 
        self.overrideEnv('BZR_TEST_PATH', './anywhere at all/')
2202
 
        path = osutils.path_from_environ('BZR_TEST_PATH')
2203
 
        self.assertIsInstance(path, unicode)
2204
 
        self.assertEqual(u'./anywhere at all/', path)
2205
 
 
2206
 
    def test_posix_path_env_ascii(self):
2207
 
        self.overrideEnv('BZR_TEST_PATH', '/tmp')
2208
 
        home = osutils._posix_path_from_environ('BZR_TEST_PATH')
2209
 
        self.assertIsInstance(home, unicode)
2210
 
        self.assertEqual(u'/tmp', home)
2211
 
 
2212
 
    def test_posix_path_env_unicode(self):
2213
 
        self.requireFeature(features.ByteStringNamedFilesystem)
2214
 
        self.overrideEnv('BZR_TEST_PATH', '/home/\xa7test')
2215
 
        self.overrideAttr(osutils, "_fs_enc", "iso8859-1")
2216
 
        self.assertEqual(u'/home/\xa7test',
2217
 
            osutils._posix_path_from_environ('BZR_TEST_PATH'))
2218
 
        osutils._fs_enc = "iso8859-5"
2219
 
        self.assertEqual(u'/home/\u0407test',
2220
 
            osutils._posix_path_from_environ('BZR_TEST_PATH'))
2221
 
        osutils._fs_enc = "utf-8"
2222
 
        self.assertRaises(errors.BadFilenameEncoding,
2223
 
            osutils._posix_path_from_environ, 'BZR_TEST_PATH')
2224
 
 
2225
 
 
2226
 
class TestGetHomeDir(tests.TestCase):
2227
 
 
2228
 
    def test_is_unicode(self):
2229
 
        home = osutils._get_home_dir()
2230
 
        self.assertIsInstance(home, unicode)
2231
 
 
2232
 
    def test_posix_homeless(self):
2233
 
        self.overrideEnv('HOME', None)
2234
 
        home = osutils._get_home_dir()
2235
 
        self.assertIsInstance(home, unicode)
2236
 
 
2237
 
    def test_posix_home_ascii(self):
2238
 
        self.overrideEnv('HOME', '/home/test')
2239
 
        home = osutils._posix_get_home_dir()
2240
 
        self.assertIsInstance(home, unicode)
2241
 
        self.assertEqual(u'/home/test', home)
2242
 
 
2243
 
    def test_posix_home_unicode(self):
2244
 
        self.requireFeature(features.ByteStringNamedFilesystem)
2245
 
        self.overrideEnv('HOME', '/home/\xa7test')
2246
 
        self.overrideAttr(osutils, "_fs_enc", "iso8859-1")
2247
 
        self.assertEqual(u'/home/\xa7test', osutils._posix_get_home_dir())
2248
 
        osutils._fs_enc = "iso8859-5"
2249
 
        self.assertEqual(u'/home/\u0407test', osutils._posix_get_home_dir())
2250
 
        osutils._fs_enc = "utf-8"
2251
 
        self.assertRaises(errors.BadFilenameEncoding,
2252
 
            osutils._posix_get_home_dir)
2253
 
 
 
2067
        self.assertEquals(self.path, 'test_file')
 
2068
        self.assertEquals(self.uid, s.st_uid)
 
2069
        self.assertEquals(self.gid, s.st_gid)
2254
2070
 
2255
2071
class TestGetuserUnicode(tests.TestCase):
2256
2072
 
2257
 
    def test_is_unicode(self):
2258
 
        user = osutils.getuser_unicode()
2259
 
        self.assertIsInstance(user, unicode)
2260
 
 
2261
 
    def envvar_to_override(self):
2262
 
        if sys.platform == "win32":
2263
 
            # Disable use of platform calls on windows so envvar is used
2264
 
            self.overrideAttr(win32utils, 'has_ctypes', False)
2265
 
            return 'USERNAME' # only variable used on windows
2266
 
        return 'LOGNAME' # first variable checked by getpass.getuser()
2267
 
 
2268
2073
    def test_ascii_user(self):
2269
 
        self.overrideEnv(self.envvar_to_override(), 'jrandom')
 
2074
        osutils.set_or_unset_env('LOGNAME', 'jrandom')
2270
2075
        self.assertEqual(u'jrandom', osutils.getuser_unicode())
2271
2076
 
2272
2077
    def test_unicode_user(self):
2278
2083
                % (osutils.get_user_encoding(),))
2279
2084
        uni_username = u'jrandom' + uni_val
2280
2085
        encoded_username = uni_username.encode(ue)
2281
 
        self.overrideEnv(self.envvar_to_override(), encoded_username)
 
2086
        osutils.set_or_unset_env('LOGNAME', encoded_username)
2282
2087
        self.assertEqual(uni_username, osutils.getuser_unicode())
2283
 
 
2284
 
 
2285
 
class TestBackupNames(tests.TestCase):
2286
 
 
2287
 
    def setUp(self):
2288
 
        super(TestBackupNames, self).setUp()
2289
 
        self.backups = []
2290
 
 
2291
 
    def backup_exists(self, name):
2292
 
        return name in self.backups
2293
 
 
2294
 
    def available_backup_name(self, name):
2295
 
        backup_name = osutils.available_backup_name(name, self.backup_exists)
2296
 
        self.backups.append(backup_name)
2297
 
        return backup_name
2298
 
 
2299
 
    def assertBackupName(self, expected, name):
2300
 
        self.assertEqual(expected, self.available_backup_name(name))
2301
 
 
2302
 
    def test_empty(self):
2303
 
        self.assertBackupName('file.~1~', 'file')
2304
 
 
2305
 
    def test_existing(self):
2306
 
        self.available_backup_name('file')
2307
 
        self.available_backup_name('file')
2308
 
        self.assertBackupName('file.~3~', 'file')
2309
 
        # Empty slots are found, this is not a strict requirement and may be
2310
 
        # revisited if we test against all implementations.
2311
 
        self.backups.remove('file.~2~')
2312
 
        self.assertBackupName('file.~2~', 'file')
2313
 
 
2314
 
 
2315
 
class TestFindExecutableInPath(tests.TestCase):
2316
 
 
2317
 
    def test_windows(self):
2318
 
        if sys.platform != 'win32':
2319
 
            raise tests.TestSkipped('test requires win32')
2320
 
        self.assertTrue(osutils.find_executable_on_path('explorer') is not None)
2321
 
        self.assertTrue(
2322
 
            osutils.find_executable_on_path('explorer.exe') is not None)
2323
 
        self.assertTrue(
2324
 
            osutils.find_executable_on_path('EXPLORER.EXE') is not None)
2325
 
        self.assertTrue(
2326
 
            osutils.find_executable_on_path('THIS SHOULD NOT EXIST') is None)
2327
 
        self.assertTrue(osutils.find_executable_on_path('file.txt') is None)
2328
 
        
2329
 
    def test_windows_app_path(self):
2330
 
        if sys.platform != 'win32':
2331
 
            raise tests.TestSkipped('test requires win32')
2332
 
        # Override PATH env var so that exe can only be found on App Path
2333
 
        self.overrideEnv('PATH', '')
2334
 
        # Internt Explorer is always registered in the App Path
2335
 
        self.assertTrue(osutils.find_executable_on_path('iexplore') is not None)
2336
 
 
2337
 
    def test_other(self):
2338
 
        if sys.platform == 'win32':
2339
 
            raise tests.TestSkipped('test requires non-win32')
2340
 
        self.assertTrue(osutils.find_executable_on_path('sh') is not None)
2341
 
        self.assertTrue(
2342
 
            osutils.find_executable_on_path('THIS SHOULD NOT EXIST') is None)
2343
 
 
2344
 
 
2345
 
class TestEnvironmentErrors(tests.TestCase):
2346
 
    """Test handling of environmental errors"""
2347
 
 
2348
 
    def test_is_oserror(self):
2349
 
        self.assertTrue(osutils.is_environment_error(
2350
 
            OSError(errno.EINVAL, "Invalid parameter")))
2351
 
 
2352
 
    def test_is_ioerror(self):
2353
 
        self.assertTrue(osutils.is_environment_error(
2354
 
            IOError(errno.EINVAL, "Invalid parameter")))
2355
 
 
2356
 
    def test_is_socket_error(self):
2357
 
        self.assertTrue(osutils.is_environment_error(
2358
 
            socket.error(errno.EINVAL, "Invalid parameter")))
2359
 
 
2360
 
    def test_is_select_error(self):
2361
 
        self.assertTrue(osutils.is_environment_error(
2362
 
            select.error(errno.EINVAL, "Invalid parameter")))
2363
 
 
2364
 
    def test_is_pywintypes_error(self):
2365
 
        self.requireFeature(features.pywintypes)
2366
 
        import pywintypes
2367
 
        self.assertTrue(osutils.is_environment_error(
2368
 
            pywintypes.error(errno.EINVAL, "Invalid parameter", "Caller")))