/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
1
# Copyright (C) 2005-2016 Canonical Ltd
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
16
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
17
"""Tests for the osutils wrapper."""
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
18
6632.1.2 by Martin
Fix tests for pump and send_all on Python 3
19
from __future__ import absolute_import, division
20
1732.1.28 by John Arbash Meinel
Add tests for fancy file types.
21
import errno
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
22
import os
4183.6.4 by Martin Pool
Separate out re_compile_checked
23
import re
6336.2.1 by Martin Packman
Add is_environment_error() and switch trace to using it
24
import select
1732.1.28 by John Arbash Meinel
Add tests for fancy file types.
25
import socket
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
26
import sys
6015.60.2 by John Arbash Meinel
Fix bug #1075108.
27
import tempfile
3504.4.2 by John Arbash Meinel
Add a test case that shows the mtime is not being returned correctly.
28
import time
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
29
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
30
from .. import (
1996.3.14 by John Arbash Meinel
lazy_import osutils and sign_my_commits
31
    errors,
5326.2.11 by Parth Malwankar
re-install lazy re compile for failing test.
32
    lazy_regex,
1996.3.14 by John Arbash Meinel
lazy_import osutils and sign_my_commits
33
    osutils,
5326.2.10 by Parth Malwankar
updated re_compile_checked tests to handle deprecation.
34
    symbol_versioning,
3504.4.1 by John Arbash Meinel
Write an alternative 'walkdirs' implementation that uses win32 apis.
35
    tests,
4695.4.1 by Martin Pool
Give a shorter/cleaner message for missing extensions
36
    trace,
2279.4.1 by Alexander Belchenko
Reimplementation of ntpath.abspath in Python for Windows98: unicode safe, UNC path safe
37
    win32utils,
1996.3.14 by John Arbash Meinel
lazy_import osutils and sign_my_commits
38
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
39
from ..sixish import (
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
40
    BytesIO,
41
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
42
from . import (
5051.4.10 by Parth Malwankar
moved ChownFeature to tests/features.py
43
    features,
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
44
    file_utils,
45
    test__walkdirs_win32,
46
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
47
from .scenarios import load_tests_apply_scenarios
4297.1.1 by Vincent Ladeuil
Trivial cleanups.
48
49
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
50
class _UTF8DirReaderFeature(features.Feature):
1739.2.12 by Robert Collins
Add ReadDirFeature as per John's review.
51
52
    def _probe(self):
53
        try:
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
54
            from .. import _readdir_pyx
3696.3.5 by Robert Collins
Streamline _walkdirs_utf8 for utf8 file systems, reducing time to traverse a mozilla tree from 1s to .6 seconds. (Robert Collins)
55
            self.reader = _readdir_pyx.UTF8DirReader
1739.2.12 by Robert Collins
Add ReadDirFeature as per John's review.
56
            return True
57
        except ImportError:
58
            return False
59
60
    def feature_name(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
61
        return 'breezy._readdir_pyx'
1739.2.12 by Robert Collins
Add ReadDirFeature as per John's review.
62
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
63
UTF8DirReaderFeature = features.ModuleAvailableFeature('breezy._readdir_pyx')
1739.2.12 by Robert Collins
Add ReadDirFeature as per John's review.
64
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
65
term_ios_feature = features.ModuleAvailableFeature('termios')
4873.2.2 by John Arbash Meinel
Change the TIOCGWINSZ test to use a _ModuleFeature. (fixes bug #492561)
66
4241.14.24 by Vincent Ladeuil
Fixed as per John's review.
67
4241.14.6 by Vincent Ladeuil
Start DirReader parametrized tests.
68
def _already_unicode(s):
69
    return s
70
4241.14.24 by Vincent Ladeuil
Fixed as per John's review.
71
4241.14.6 by Vincent Ladeuil
Start DirReader parametrized tests.
72
def _utf8_to_unicode(s):
73
    return s.decode('UTF-8')
74
4241.14.24 by Vincent Ladeuil
Fixed as per John's review.
75
4241.14.6 by Vincent Ladeuil
Start DirReader parametrized tests.
76
def dir_reader_scenarios():
77
    # For each dir reader we define:
78
79
    # - native_to_unicode: a function converting the native_abspath as returned
80
    #   by DirReader.read_dir to its unicode representation
81
82
    # UnicodeDirReader is the fallback, it should be tested on all platforms.
4241.14.24 by Vincent Ladeuil
Fixed as per John's review.
83
    scenarios = [('unicode',
84
                  dict(_dir_reader_class=osutils.UnicodeDirReader,
85
                       _native_to_unicode=_already_unicode))]
4241.14.6 by Vincent Ladeuil
Start DirReader parametrized tests.
86
    # Some DirReaders are platform specific and even there they may not be
87
    # available.
88
    if UTF8DirReaderFeature.available():
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
89
        from .. import _readdir_pyx
4241.14.24 by Vincent Ladeuil
Fixed as per John's review.
90
        scenarios.append(('utf8',
91
                          dict(_dir_reader_class=_readdir_pyx.UTF8DirReader,
92
                               _native_to_unicode=_utf8_to_unicode)))
4241.14.6 by Vincent Ladeuil
Start DirReader parametrized tests.
93
4913.2.24 by John Arbash Meinel
Track down a few more import typos.
94
    if test__walkdirs_win32.win32_readdir_feature.available():
4241.14.6 by Vincent Ladeuil
Start DirReader parametrized tests.
95
        try:
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
96
            from .. import _walkdirs_win32
4241.14.24 by Vincent Ladeuil
Fixed as per John's review.
97
            scenarios.append(
98
                ('win32',
99
                 dict(_dir_reader_class=_walkdirs_win32.Win32ReadDir,
4789.25.3 by John Arbash Meinel
For DirReader tests, the 'fs path' on win32 is a Unicode string, no need to decode/encode.
100
                      _native_to_unicode=_already_unicode)))
4241.14.6 by Vincent Ladeuil
Start DirReader parametrized tests.
101
        except ImportError:
102
            pass
103
    return scenarios
104
105
5559.2.2 by Martin Pool
Change to using standard load_tests_apply_scenarios.
106
load_tests = load_tests_apply_scenarios
4241.14.6 by Vincent Ladeuil
Start DirReader parametrized tests.
107
1739.2.12 by Robert Collins
Add ReadDirFeature as per John's review.
108
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
109
class TestContainsWhitespace(tests.TestCase):
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
110
2249.2.1 by John Arbash Meinel
(John Arbash Meinel) hard-code the whitespace chars to avoid problems in some locales.
111
    def test_contains_whitespace(self):
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
112
        self.assertTrue(osutils.contains_whitespace(u' '))
113
        self.assertTrue(osutils.contains_whitespace(u'hello there'))
114
        self.assertTrue(osutils.contains_whitespace(u'hellothere\n'))
115
        self.assertTrue(osutils.contains_whitespace(u'hello\nthere'))
116
        self.assertTrue(osutils.contains_whitespace(u'hello\rthere'))
117
        self.assertTrue(osutils.contains_whitespace(u'hello\tthere'))
2249.2.1 by John Arbash Meinel
(John Arbash Meinel) hard-code the whitespace chars to avoid problems in some locales.
118
119
        # \xa0 is "Non-breaking-space" which on some python locales thinks it
120
        # is whitespace, but we do not.
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
121
        self.assertFalse(osutils.contains_whitespace(u''))
122
        self.assertFalse(osutils.contains_whitespace(u'hellothere'))
123
        self.assertFalse(osutils.contains_whitespace(u'hello\xa0there'))
2249.2.1 by John Arbash Meinel
(John Arbash Meinel) hard-code the whitespace chars to avoid problems in some locales.
124
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
125
126
class TestRename(tests.TestCaseInTempDir):
127
4789.17.1 by John Arbash Meinel
Change fancy_rename slightly.
128
    def create_file(self, filename, content):
129
        f = open(filename, 'wb')
130
        try:
131
            f.write(content)
132
        finally:
133
            f.close()
134
4789.17.2 by John Arbash Meinel
Also handle the case when source *and* target does not exist.
135
    def _fancy_rename(self, a, b):
136
        osutils.fancy_rename(a, b, rename_func=os.rename,
137
                             unlink_func=os.unlink)
138
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
139
    def test_fancy_rename(self):
140
        # This should work everywhere
4789.17.1 by John Arbash Meinel
Change fancy_rename slightly.
141
        self.create_file('a', 'something in a\n')
4789.17.2 by John Arbash Meinel
Also handle the case when source *and* target does not exist.
142
        self._fancy_rename('a', 'b')
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
143
        self.assertPathDoesNotExist('a')
144
        self.assertPathExists('b')
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
145
        self.check_file_contents('b', 'something in a\n')
146
4789.17.1 by John Arbash Meinel
Change fancy_rename slightly.
147
        self.create_file('a', 'new something in a\n')
4789.17.2 by John Arbash Meinel
Also handle the case when source *and* target does not exist.
148
        self._fancy_rename('b', 'a')
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
149
150
        self.check_file_contents('a', 'something in a\n')
151
4789.17.1 by John Arbash Meinel
Change fancy_rename slightly.
152
    def test_fancy_rename_fails_source_missing(self):
153
        # An exception should be raised, and the target should be left in place
154
        self.create_file('target', 'data in target\n')
4789.17.2 by John Arbash Meinel
Also handle the case when source *and* target does not exist.
155
        self.assertRaises((IOError, OSError), self._fancy_rename,
4789.17.1 by John Arbash Meinel
Change fancy_rename slightly.
156
                          'missingsource', 'target')
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
157
        self.assertPathExists('target')
4789.17.1 by John Arbash Meinel
Change fancy_rename slightly.
158
        self.check_file_contents('target', 'data in target\n')
159
4789.17.2 by John Arbash Meinel
Also handle the case when source *and* target does not exist.
160
    def test_fancy_rename_fails_if_source_and_target_missing(self):
161
        self.assertRaises((IOError, OSError), self._fancy_rename,
162
                          'missingsource', 'missingtarget')
163
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
164
    def test_rename(self):
165
        # Rename should be semi-atomic on all platforms
4789.17.1 by John Arbash Meinel
Change fancy_rename slightly.
166
        self.create_file('a', 'something in a\n')
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
167
        osutils.rename('a', 'b')
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
168
        self.assertPathDoesNotExist('a')
169
        self.assertPathExists('b')
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
170
        self.check_file_contents('b', 'something in a\n')
171
4789.17.1 by John Arbash Meinel
Change fancy_rename slightly.
172
        self.create_file('a', 'new something in a\n')
1185.31.47 by John Arbash Meinel
Added a fancy footwork rename to osutils, made SftpTransport use it.
173
        osutils.rename('b', 'a')
174
175
        self.check_file_contents('a', 'something in a\n')
176
177
    # TODO: test fancy_rename using a MemoryTransport
178
2978.8.2 by Alexander Belchenko
teach fancy_rename to handle change case renames in possible case-insensitive filesystem
179
    def test_rename_change_case(self):
180
        # on Windows we should be able to change filename case by rename
2978.8.1 by Alexander Belchenko
Rename on Windows is able to change filename case. (#77740)
181
        self.build_tree(['a', 'b/'])
182
        osutils.rename('a', 'A')
183
        osutils.rename('b', 'B')
2978.8.2 by Alexander Belchenko
teach fancy_rename to handle change case renames in possible case-insensitive filesystem
184
        # we can't use failUnlessExists on case-insensitive filesystem
185
        # so try to check shape of the tree
2978.8.1 by Alexander Belchenko
Rename on Windows is able to change filename case. (#77740)
186
        shape = sorted(os.listdir('.'))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
187
        self.assertEqual(['A', 'B'], shape)
2978.8.1 by Alexander Belchenko
Rename on Windows is able to change filename case. (#77740)
188
6468.6.1 by Ross Lagerwall
Change osutils.rename to extend any exception information given from os.rename.
189
    def test_rename_exception(self):
190
        try:
191
            osutils.rename('nonexistent_path', 'different_nonexistent_path')
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
192
        except OSError as e:
6468.6.1 by Ross Lagerwall
Change osutils.rename to extend any exception information given from os.rename.
193
            self.assertEqual(e.old_filename, 'nonexistent_path')
194
            self.assertEqual(e.new_filename, 'different_nonexistent_path')
6468.6.2 by Ross Lagerwall
Check that exception string contains both filenames in test_rename_exception.
195
            self.assertTrue('nonexistent_path' in e.strerror)
196
            self.assertTrue('different_nonexistent_path' in e.strerror)
6468.6.1 by Ross Lagerwall
Change osutils.rename to extend any exception information given from os.rename.
197
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
198
199
class TestRandChars(tests.TestCase):
200
1553.5.5 by Martin Pool
New utility routine rand_chars
201
    def test_01_rand_chars_empty(self):
202
        result = osutils.rand_chars(0)
203
        self.assertEqual(result, '')
204
205
    def test_02_rand_chars_100(self):
206
        result = osutils.rand_chars(100)
207
        self.assertEqual(len(result), 100)
208
        self.assertEqual(type(result), str)
209
        self.assertContainsRe(result, r'^[a-z0-9]{100}$')
210
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
211
212
class TestIsInside(tests.TestCase):
213
1996.3.14 by John Arbash Meinel
lazy_import osutils and sign_my_commits
214
    def test_is_inside(self):
215
        is_inside = osutils.is_inside
216
        self.assertTrue(is_inside('src', 'src/foo.c'))
217
        self.assertFalse(is_inside('src', 'srccontrol'))
218
        self.assertTrue(is_inside('src', 'src/a/a/a/foo.c'))
219
        self.assertTrue(is_inside('foo.c', 'foo.c'))
220
        self.assertFalse(is_inside('foo.c', ''))
221
        self.assertTrue(is_inside('', 'foo.c'))
1534.3.1 by Robert Collins
* bzrlib.osutils.safe_unicode now exists to provide parameter coercion
222
2729.2.4 by Martin Pool
move some osutils-related tests from test_inv to test_osutils
223
    def test_is_inside_any(self):
4241.9.3 by Vincent Ladeuil
Fix two more test failures specific to OSX.
224
        SRC_FOO_C = osutils.pathjoin('src', 'foo.c')
2729.2.4 by Martin Pool
move some osutils-related tests from test_inv to test_osutils
225
        for dirs, fn in [(['src', 'doc'], SRC_FOO_C),
226
                         (['src'], SRC_FOO_C),
227
                         (['src'], 'src'),
228
                         ]:
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
229
            self.assertTrue(osutils.is_inside_any(dirs, fn))
2729.2.4 by Martin Pool
move some osutils-related tests from test_inv to test_osutils
230
        for dirs, fn in [(['src'], 'srccontrol'),
231
                         (['src'], 'srccontrol/foo')]:
4241.9.3 by Vincent Ladeuil
Fix two more test failures specific to OSX.
232
            self.assertFalse(osutils.is_inside_any(dirs, fn))
2729.2.4 by Martin Pool
move some osutils-related tests from test_inv to test_osutils
233
234
    def test_is_inside_or_parent_of_any(self):
235
        for dirs, fn in [(['src', 'doc'], 'src/foo.c'),
236
                         (['src'], 'src/foo.c'),
237
                         (['src/bar.c'], 'src'),
238
                         (['src/bar.c', 'bla/foo.c'], 'src'),
239
                         (['src'], 'src'),
240
                         ]:
6614.1.1 by Vincent Ladeuil
Fix assert_ being deprecated by using assertTrue.
241
            self.assertTrue(osutils.is_inside_or_parent_of_any(dirs, fn))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
242
2729.2.4 by Martin Pool
move some osutils-related tests from test_inv to test_osutils
243
        for dirs, fn in [(['src'], 'srccontrol'),
244
                         (['srccontrol/foo.c'], 'src'),
245
                         (['src'], 'srccontrol/foo')]:
4241.9.3 by Vincent Ladeuil
Fix two more test failures specific to OSX.
246
            self.assertFalse(osutils.is_inside_or_parent_of_any(dirs, fn))
2729.2.4 by Martin Pool
move some osutils-related tests from test_inv to test_osutils
247
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
248
5752.2.10 by John Arbash Meinel
Add a test that fstat and lstat match.
249
class TestLstat(tests.TestCaseInTempDir):
250
251
    def test_lstat_matches_fstat(self):
252
        # On Windows, lstat and fstat don't always agree, primarily in the
253
        # 'st_ino' and 'st_dev' fields. So we force them to be '0' in our
254
        # custom implementation.
255
        if sys.platform == 'win32':
256
            # We only have special lstat/fstat if we have the extension.
257
            # Without it, we may end up re-reading content when we don't have
258
            # to, but otherwise it doesn't effect correctness.
259
            self.requireFeature(test__walkdirs_win32.win32_readdir_feature)
260
        f = open('test-file.txt', 'wb')
261
        self.addCleanup(f.close)
262
        f.write('some content\n')
263
        f.flush()
264
        self.assertEqualStat(osutils.fstat(f.fileno()),
265
                             osutils.lstat('test-file.txt'))
266
267
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
268
class TestRmTree(tests.TestCaseInTempDir):
269
1692.7.6 by Martin Pool
[patch] force deletion of trees containing readonly files (alexander)
270
    def test_rmtree(self):
271
        # Check to remove tree with read-only files/dirs
272
        os.mkdir('dir')
273
        f = file('dir/file', 'w')
274
        f.write('spam')
275
        f.close()
276
        # would like to also try making the directory readonly, but at the
277
        # moment python shutil.rmtree doesn't handle that properly - it would
278
        # need to chmod the directory before removing things inside it - deferred
279
        # for now -- mbp 20060505
280
        # osutils.make_readonly('dir')
281
        osutils.make_readonly('dir/file')
282
283
        osutils.rmtree('dir')
284
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
285
        self.assertPathDoesNotExist('dir/file')
286
        self.assertPathDoesNotExist('dir')
1692.7.6 by Martin Pool
[patch] force deletion of trees containing readonly files (alexander)
287
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
288
4490.1.2 by Martin Pool
test and news for forcing readonly deletion
289
class TestDeleteAny(tests.TestCaseInTempDir):
290
291
    def test_delete_any_readonly(self):
292
        # from <https://bugs.launchpad.net/bzr/+bug/218206>
293
        self.build_tree(['d/', 'f'])
294
        osutils.make_readonly('d')
295
        osutils.make_readonly('f')
296
297
        osutils.delete_any('f')
298
        osutils.delete_any('d')
299
300
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
301
class TestKind(tests.TestCaseInTempDir):
302
1732.1.10 by John Arbash Meinel
Updated version of file_kind. Rather than multiple function calls, one mask + dictionary lookup
303
    def test_file_kind(self):
304
        self.build_tree(['file', 'dir/'])
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
305
        self.assertEqual('file', osutils.file_kind('file'))
306
        self.assertEqual('directory', osutils.file_kind('dir/'))
1732.1.10 by John Arbash Meinel
Updated version of file_kind. Rather than multiple function calls, one mask + dictionary lookup
307
        if osutils.has_symlinks():
308
            os.symlink('symlink', 'symlink')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
309
            self.assertEqual('symlink', osutils.file_kind('symlink'))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
310
1732.1.28 by John Arbash Meinel
Add tests for fancy file types.
311
        # TODO: jam 20060529 Test a block device
312
        try:
313
            os.lstat('/dev/null')
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
314
        except OSError as e:
1732.1.28 by John Arbash Meinel
Add tests for fancy file types.
315
            if e.errno not in (errno.ENOENT,):
316
                raise
317
        else:
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
318
            self.assertEqual('chardev', osutils.file_kind('/dev/null'))
1732.1.28 by John Arbash Meinel
Add tests for fancy file types.
319
320
        mkfifo = getattr(os, 'mkfifo', None)
321
        if mkfifo:
322
            mkfifo('fifo')
323
            try:
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
324
                self.assertEqual('fifo', osutils.file_kind('fifo'))
1732.1.28 by John Arbash Meinel
Add tests for fancy file types.
325
            finally:
326
                os.remove('fifo')
327
328
        AF_UNIX = getattr(socket, 'AF_UNIX', None)
329
        if AF_UNIX:
330
            s = socket.socket(AF_UNIX)
331
            s.bind('socket')
332
            try:
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
333
                self.assertEqual('socket', osutils.file_kind('socket'))
1732.1.28 by John Arbash Meinel
Add tests for fancy file types.
334
            finally:
335
                os.remove('socket')
1732.1.10 by John Arbash Meinel
Updated version of file_kind. Rather than multiple function calls, one mask + dictionary lookup
336
1551.10.27 by Aaron Bentley
Add a kind marker for subtrees
337
    def test_kind_marker(self):
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
338
        self.assertEqual("", osutils.kind_marker("file"))
339
        self.assertEqual("/", osutils.kind_marker('directory'))
340
        self.assertEqual("/", osutils.kind_marker(osutils._directory_kind))
341
        self.assertEqual("@", osutils.kind_marker("symlink"))
342
        self.assertEqual("+", osutils.kind_marker("tree-reference"))
5024.1.2 by John Arbash Meinel
Switch so that all unknown files get an empty marker, rather than failing.
343
        self.assertEqual("", osutils.kind_marker("fifo"))
344
        self.assertEqual("", osutils.kind_marker("socket"))
345
        self.assertEqual("", osutils.kind_marker("unknown"))
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
346
347
348
class TestUmask(tests.TestCaseInTempDir):
1551.10.27 by Aaron Bentley
Add a kind marker for subtrees
349
1755.3.7 by John Arbash Meinel
Clean up and write tests for permissions. Now we use fstat which should be cheap, and lets us check the permissions and the file size
350
    def test_get_umask(self):
351
        if sys.platform == 'win32':
352
            # umask always returns '0', no way to set it
353
            self.assertEqual(0, osutils.get_umask())
354
            return
355
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
356
        orig_umask = osutils.get_umask()
357
        self.addCleanup(os.umask, orig_umask)
6619.3.14 by Jelmer Vernooij
Convert some octal numbers to new notations.
358
        os.umask(0o222)
359
        self.assertEqual(0o222, osutils.get_umask())
360
        os.umask(0o022)
361
        self.assertEqual(0o022, osutils.get_umask())
362
        os.umask(0o002)
363
        self.assertEqual(0o002, osutils.get_umask())
364
        os.umask(0o027)
365
        self.assertEqual(0o027, osutils.get_umask())
1755.3.7 by John Arbash Meinel
Clean up and write tests for permissions. Now we use fstat which should be cheap, and lets us check the permissions and the file size
366
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
367
368
class TestDateTime(tests.TestCase):
369
1957.1.15 by John Arbash Meinel
Review feedback from Robert
370
    def assertFormatedDelta(self, expected, seconds):
371
        """Assert osutils.format_delta formats as expected"""
372
        actual = osutils.format_delta(seconds)
373
        self.assertEqual(expected, actual)
374
1957.1.4 by John Arbash Meinel
create a helper for formatting a time delta
375
    def test_format_delta(self):
1957.1.15 by John Arbash Meinel
Review feedback from Robert
376
        self.assertFormatedDelta('0 seconds ago', 0)
377
        self.assertFormatedDelta('1 second ago', 1)
378
        self.assertFormatedDelta('10 seconds ago', 10)
379
        self.assertFormatedDelta('59 seconds ago', 59)
380
        self.assertFormatedDelta('89 seconds ago', 89)
381
        self.assertFormatedDelta('1 minute, 30 seconds ago', 90)
382
        self.assertFormatedDelta('3 minutes, 0 seconds ago', 180)
383
        self.assertFormatedDelta('3 minutes, 1 second ago', 181)
384
        self.assertFormatedDelta('10 minutes, 15 seconds ago', 615)
385
        self.assertFormatedDelta('30 minutes, 59 seconds ago', 1859)
386
        self.assertFormatedDelta('31 minutes, 0 seconds ago', 1860)
387
        self.assertFormatedDelta('60 minutes, 0 seconds ago', 3600)
388
        self.assertFormatedDelta('89 minutes, 59 seconds ago', 5399)
389
        self.assertFormatedDelta('1 hour, 30 minutes ago', 5400)
390
        self.assertFormatedDelta('2 hours, 30 minutes ago', 9017)
391
        self.assertFormatedDelta('10 hours, 0 minutes ago', 36000)
392
        self.assertFormatedDelta('24 hours, 0 minutes ago', 86400)
393
        self.assertFormatedDelta('35 hours, 59 minutes ago', 129599)
394
        self.assertFormatedDelta('36 hours, 0 minutes ago', 129600)
395
        self.assertFormatedDelta('36 hours, 0 minutes ago', 129601)
396
        self.assertFormatedDelta('36 hours, 1 minute ago', 129660)
397
        self.assertFormatedDelta('36 hours, 1 minute ago', 129661)
398
        self.assertFormatedDelta('84 hours, 10 minutes ago', 303002)
1957.1.4 by John Arbash Meinel
create a helper for formatting a time delta
399
400
        # We handle when time steps the wrong direction because computers
401
        # don't have synchronized clocks.
1957.1.15 by John Arbash Meinel
Review feedback from Robert
402
        self.assertFormatedDelta('84 hours, 10 minutes in the future', -303002)
403
        self.assertFormatedDelta('1 second in the future', -1)
404
        self.assertFormatedDelta('2 seconds in the future', -2)
1957.1.4 by John Arbash Meinel
create a helper for formatting a time delta
405
3144.1.1 by Lukáš Lalinský
Fixed error reporting of unsupported timezone format.
406
    def test_format_date(self):
407
        self.assertRaises(errors.UnsupportedTimezoneFormat,
408
            osutils.format_date, 0, timezone='foo')
3526.5.4 by Martin von Gagern
Use separate function format_local_date for local weekday formats in unicode.
409
        self.assertIsInstance(osutils.format_date(0), str)
410
        self.assertIsInstance(osutils.format_local_date(0), unicode)
411
        # Testing for the actual value of the local weekday without
3526.5.2 by Martin von Gagern
Check output type of format_date
412
        # duplicating the code from format_date is difficult.
413
        # Instead blackbox.test_locale should check for localized
414
        # dates once they do occur in output strings.
3144.1.1 by Lukáš Lalinský
Fixed error reporting of unsupported timezone format.
415
4379.4.2 by Ian Clatworthy
add NEWS item and tests for new date formatting API
416
    def test_format_date_with_offset_in_original_timezone(self):
417
        self.assertEqual("Thu 1970-01-01 00:00:00 +0000",
418
            osutils.format_date_with_offset_in_original_timezone(0))
419
        self.assertEqual("Fri 1970-01-02 03:46:40 +0000",
420
            osutils.format_date_with_offset_in_original_timezone(100000))
421
        self.assertEqual("Fri 1970-01-02 05:46:40 +0200",
422
            osutils.format_date_with_offset_in_original_timezone(100000, 7200))
423
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
424
    def test_local_time_offset(self):
425
        """Test that local_time_offset() returns a sane value."""
426
        offset = osutils.local_time_offset()
427
        self.assertTrue(isinstance(offset, int))
428
        # Test that the offset is no more than a eighteen hours in
429
        # either direction.
430
        # Time zone handling is system specific, so it is difficult to
431
        # do more specific tests, but a value outside of this range is
432
        # probably wrong.
433
        eighteen_hours = 18 * 3600
434
        self.assertTrue(-eighteen_hours < offset < eighteen_hours)
435
436
    def test_local_time_offset_with_timestamp(self):
437
        """Test that local_time_offset() works with a timestamp."""
438
        offset = osutils.local_time_offset(1000000000.1234567)
439
        self.assertTrue(isinstance(offset, int))
440
        eighteen_hours = 18 * 3600
441
        self.assertTrue(-eighteen_hours < offset < eighteen_hours)
442
443
6015.60.2 by John Arbash Meinel
Fix bug #1075108.
444
class TestFdatasync(tests.TestCaseInTempDir):
445
446
    def do_fdatasync(self):
447
        f = tempfile.NamedTemporaryFile()
448
        osutils.fdatasync(f.fileno())
449
        f.close()
450
451
    @staticmethod
6015.60.4 by John Arbash Meinel
Found it called EOPNOTSUPP on a platform, include that spelling as well.
452
    def raise_eopnotsupp(*args, **kwargs):
453
        raise IOError(errno.EOPNOTSUPP, os.strerror(errno.EOPNOTSUPP))
454
455
    @staticmethod
6015.60.2 by John Arbash Meinel
Fix bug #1075108.
456
    def raise_enotsup(*args, **kwargs):
457
        raise IOError(errno.ENOTSUP, os.strerror(errno.ENOTSUP))
458
459
    def test_fdatasync_handles_system_function(self):
460
        self.overrideAttr(os, "fdatasync")
461
        self.do_fdatasync()
462
463
    def test_fdatasync_handles_no_fdatasync_no_fsync(self):
464
        self.overrideAttr(os, "fdatasync")
465
        self.overrideAttr(os, "fsync")
466
        self.do_fdatasync()
467
6015.60.4 by John Arbash Meinel
Found it called EOPNOTSUPP on a platform, include that spelling as well.
468
    def test_fdatasync_handles_no_EOPNOTSUPP(self):
469
        self.overrideAttr(errno, "EOPNOTSUPP")
6015.60.2 by John Arbash Meinel
Fix bug #1075108.
470
        self.do_fdatasync()
471
472
    def test_fdatasync_catches_ENOTSUP(self):
473
        enotsup = getattr(errno, "ENOTSUP", None)
474
        if enotsup is None:
475
            raise tests.TestNotApplicable("No ENOTSUP on this platform")
476
        self.overrideAttr(os, "fdatasync", self.raise_enotsup)
477
        self.do_fdatasync()
478
6015.60.4 by John Arbash Meinel
Found it called EOPNOTSUPP on a platform, include that spelling as well.
479
    def test_fdatasync_catches_EOPNOTSUPP(self):
480
        enotsup = getattr(errno, "EOPNOTSUPP", None)
481
        if enotsup is None:
482
            raise tests.TestNotApplicable("No EOPNOTSUPP on this platform")
483
        self.overrideAttr(os, "fdatasync", self.raise_eopnotsupp)
484
        self.do_fdatasync()
485
6015.60.2 by John Arbash Meinel
Fix bug #1075108.
486
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
487
class TestLinks(tests.TestCaseInTempDir):
488
2091.3.7 by Aaron Bentley
Rename real_parent to dereferenced_path
489
    def test_dereference_path(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
490
        self.requireFeature(features.SymlinkFeature)
2091.3.5 by Aaron Bentley
Move realpath functionality into osutils
491
        cwd = osutils.realpath('.')
492
        os.mkdir('bar')
493
        bar_path = osutils.pathjoin(cwd, 'bar')
494
        # Using './' to avoid bug #1213894 (first path component not
495
        # dereferenced) in Python 2.4.1 and earlier
496
        self.assertEqual(bar_path, osutils.realpath('./bar'))
497
        os.symlink('bar', 'foo')
498
        self.assertEqual(bar_path, osutils.realpath('./foo'))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
499
2091.3.5 by Aaron Bentley
Move realpath functionality into osutils
500
        # Does not dereference terminal symlinks
501
        foo_path = osutils.pathjoin(cwd, 'foo')
2091.3.7 by Aaron Bentley
Rename real_parent to dereferenced_path
502
        self.assertEqual(foo_path, osutils.dereference_path('./foo'))
2091.3.5 by Aaron Bentley
Move realpath functionality into osutils
503
504
        # Dereferences parent symlinks
505
        os.mkdir('bar/baz')
506
        baz_path = osutils.pathjoin(bar_path, 'baz')
2091.3.7 by Aaron Bentley
Rename real_parent to dereferenced_path
507
        self.assertEqual(baz_path, osutils.dereference_path('./foo/baz'))
2091.3.5 by Aaron Bentley
Move realpath functionality into osutils
508
509
        # Dereferences parent symlinks that are the first path element
2091.3.7 by Aaron Bentley
Rename real_parent to dereferenced_path
510
        self.assertEqual(baz_path, osutils.dereference_path('foo/baz'))
2091.3.5 by Aaron Bentley
Move realpath functionality into osutils
511
512
        # Dereferences parent symlinks in absolute paths
513
        foo_baz_path = osutils.pathjoin(foo_path, 'baz')
2091.3.7 by Aaron Bentley
Rename real_parent to dereferenced_path
514
        self.assertEqual(baz_path, osutils.dereference_path(foo_baz_path))
2091.3.5 by Aaron Bentley
Move realpath functionality into osutils
515
2568.1.1 by John Arbash Meinel
(Elliot Murphy) Use os.lstat rather than os.stat for osutils.make_readonly/make_writeable
516
    def test_changing_access(self):
517
        f = file('file', 'w')
518
        f.write('monkey')
519
        f.close()
520
521
        # Make a file readonly
522
        osutils.make_readonly('file')
2949.6.2 by Alexander Belchenko
more changes osutils.lstat -> os.lstat
523
        mode = os.lstat('file').st_mode
6619.3.14 by Jelmer Vernooij
Convert some octal numbers to new notations.
524
        self.assertEqual(mode, mode & 0o777555)
2568.1.1 by John Arbash Meinel
(Elliot Murphy) Use os.lstat rather than os.stat for osutils.make_readonly/make_writeable
525
526
        # Make a file writable
527
        osutils.make_writable('file')
2949.6.2 by Alexander Belchenko
more changes osutils.lstat -> os.lstat
528
        mode = os.lstat('file').st_mode
6619.3.14 by Jelmer Vernooij
Convert some octal numbers to new notations.
529
        self.assertEqual(mode, mode | 0o200)
2568.1.1 by John Arbash Meinel
(Elliot Murphy) Use os.lstat rather than os.stat for osutils.make_readonly/make_writeable
530
531
        if osutils.has_symlinks():
532
            # should not error when handed a symlink
533
            os.symlink('nonexistent', 'dangling')
534
            osutils.make_readonly('dangling')
535
            osutils.make_writable('dangling')
536
3287.18.26 by Matt McClure
Addresses concerns raised in
537
    def test_host_os_dereferences_symlinks(self):
538
        osutils.host_os_dereferences_symlinks()
539
2324.2.1 by Dmitry Vasiliev
kind_marker() optimization
540
4241.14.3 by Vincent Ladeuil
Cleanup imports.
541
class TestCanonicalRelPath(tests.TestCaseInTempDir):
3794.5.36 by Mark Hammond
test for, and fix problem with canonical_relpath when the tail does not exist.
542
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
543
    _test_needs_features = [features.CaseInsCasePresFilenameFeature]
3794.5.36 by Mark Hammond
test for, and fix problem with canonical_relpath when the tail does not exist.
544
545
    def test_canonical_relpath_simple(self):
546
        f = file('MixedCaseName', 'w')
547
        f.close()
4707.1.1 by Vincent Ladeuil
Fix OSX and FreeBSD failures.
548
        actual = osutils.canonical_relpath(self.test_base_dir, 'mixedcasename')
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
549
        self.assertEqual('work/MixedCaseName', actual)
3794.5.36 by Mark Hammond
test for, and fix problem with canonical_relpath when the tail does not exist.
550
551
    def test_canonical_relpath_missing_tail(self):
552
        os.mkdir('MixedCaseParent')
4707.1.1 by Vincent Ladeuil
Fix OSX and FreeBSD failures.
553
        actual = osutils.canonical_relpath(self.test_base_dir,
4241.9.3 by Vincent Ladeuil
Fix two more test failures specific to OSX.
554
                                           'mixedcaseparent/nochild')
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
555
        self.assertEqual('work/MixedCaseParent/nochild', actual)
3794.5.36 by Mark Hammond
test for, and fix problem with canonical_relpath when the tail does not exist.
556
557
4634.70.2 by John Arbash Meinel
Fix bug #322807, teach cicp_canonical_relpath how to handle
558
class Test_CICPCanonicalRelpath(tests.TestCaseWithTransport):
559
560
    def assertRelpath(self, expected, base, path):
561
        actual = osutils._cicp_canonical_relpath(base, path)
562
        self.assertEqual(expected, actual)
563
564
    def test_simple(self):
565
        self.build_tree(['MixedCaseName'])
566
        base = osutils.realpath(self.get_transport('.').local_abspath('.'))
567
        self.assertRelpath('MixedCaseName', base, 'mixedcAsename')
568
569
    def test_subdir_missing_tail(self):
570
        self.build_tree(['MixedCaseParent/', 'MixedCaseParent/a_child'])
571
        base = osutils.realpath(self.get_transport('.').local_abspath('.'))
572
        self.assertRelpath('MixedCaseParent/a_child', base,
573
                           'MixedCaseParent/a_child')
574
        self.assertRelpath('MixedCaseParent/a_child', base,
575
                           'MixedCaseParent/A_Child')
576
        self.assertRelpath('MixedCaseParent/not_child', base,
577
                           'MixedCaseParent/not_child')
578
4634.70.6 by John Arbash Meinel
Mix up the test a bit. On Windows we don't run the '/' test
579
    def test_at_root_slash(self):
4634.70.2 by John Arbash Meinel
Fix bug #322807, teach cicp_canonical_relpath how to handle
580
        # We can't test this on Windows, because it has a 'MIN_ABS_PATHLENGTH'
581
        # check...
4634.70.4 by John Arbash Meinel
Take spiv's suggestion and move the '/' test to another test case.
582
        if osutils.MIN_ABS_PATHLENGTH > 1:
4634.70.6 by John Arbash Meinel
Mix up the test a bit. On Windows we don't run the '/' test
583
            raise tests.TestSkipped('relpath requires %d chars'
584
                                    % osutils.MIN_ABS_PATHLENGTH)
4634.70.4 by John Arbash Meinel
Take spiv's suggestion and move the '/' test to another test case.
585
        self.assertRelpath('foo', '/', '/foo')
4634.70.2 by John Arbash Meinel
Fix bug #322807, teach cicp_canonical_relpath how to handle
586
4634.70.6 by John Arbash Meinel
Mix up the test a bit. On Windows we don't run the '/' test
587
    def test_at_root_drive(self):
588
        if sys.platform != 'win32':
589
            raise tests.TestNotApplicable('we can only test drive-letter relative'
590
                                          ' paths on Windows where we have drive'
591
                                          ' letters.')
4634.70.2 by John Arbash Meinel
Fix bug #322807, teach cicp_canonical_relpath how to handle
592
        # see bug #322807
593
        # The specific issue is that when at the root of a drive, 'abspath'
594
        # returns "C:/" or just "/". However, the code assumes that abspath
595
        # always returns something like "C:/foo" or "/foo" (no trailing slash).
596
        self.assertRelpath('foo', 'C:/', 'C:/foo')
597
        self.assertRelpath('foo', 'X:/', 'X:/foo')
598
        self.assertRelpath('foo', 'X:/', 'X://foo')
599
600
4241.14.3 by Vincent Ladeuil
Cleanup imports.
601
class TestPumpFile(tests.TestCase):
3408.6.1 by Eric Holmberg
Fix for Bug #215426 in which bzr can cause a MemoryError in socket.recv while
602
    """Test pumpfile method."""
4241.14.3 by Vincent Ladeuil
Cleanup imports.
603
3408.6.1 by Eric Holmberg
Fix for Bug #215426 in which bzr can cause a MemoryError in socket.recv while
604
    def setUp(self):
6552.1.3 by Vincent Ladeuil
Use super() instead of calling <base>.setup(self), as the original fix illustrated a too-easy-to-fall-into trap.
605
        super(TestPumpFile, self).setUp()
3408.6.1 by Eric Holmberg
Fix for Bug #215426 in which bzr can cause a MemoryError in socket.recv while
606
        # create a test datablock
607
        self.block_size = 512
6632.1.2 by Martin
Fix tests for pump and send_all on Python 3
608
        pattern = b'0123456789ABCDEF'
609
        self.test_data = pattern * (3 * self.block_size // len(pattern))
3408.6.1 by Eric Holmberg
Fix for Bug #215426 in which bzr can cause a MemoryError in socket.recv while
610
        self.test_data_len = len(self.test_data)
611
612
    def test_bracket_block_size(self):
613
        """Read data in blocks with the requested read size bracketing the
614
        block size."""
615
        # make sure test data is larger than max read size
616
        self.assertTrue(self.test_data_len > self.block_size)
617
4241.14.3 by Vincent Ladeuil
Cleanup imports.
618
        from_file = file_utils.FakeReadFile(self.test_data)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
619
        to_file = BytesIO()
3408.6.1 by Eric Holmberg
Fix for Bug #215426 in which bzr can cause a MemoryError in socket.recv while
620
6632.1.2 by Martin
Fix tests for pump and send_all on Python 3
621
        # read (max // 2) bytes and verify read size wasn't affected
622
        num_bytes_to_read = self.block_size // 2
4241.9.3 by Vincent Ladeuil
Fix two more test failures specific to OSX.
623
        osutils.pumpfile(from_file, to_file, num_bytes_to_read, self.block_size)
3408.6.1 by Eric Holmberg
Fix for Bug #215426 in which bzr can cause a MemoryError in socket.recv while
624
        self.assertEqual(from_file.get_max_read_size(), num_bytes_to_read)
625
        self.assertEqual(from_file.get_read_count(), 1)
626
627
        # read (max) bytes and verify read size wasn't affected
628
        num_bytes_to_read = self.block_size
629
        from_file.reset_read_count()
4241.9.3 by Vincent Ladeuil
Fix two more test failures specific to OSX.
630
        osutils.pumpfile(from_file, to_file, num_bytes_to_read, self.block_size)
3408.6.1 by Eric Holmberg
Fix for Bug #215426 in which bzr can cause a MemoryError in socket.recv while
631
        self.assertEqual(from_file.get_max_read_size(), num_bytes_to_read)
632
        self.assertEqual(from_file.get_read_count(), 1)
633
634
        # read (max + 1) bytes and verify read size was limited
635
        num_bytes_to_read = self.block_size + 1
636
        from_file.reset_read_count()
4241.9.3 by Vincent Ladeuil
Fix two more test failures specific to OSX.
637
        osutils.pumpfile(from_file, to_file, num_bytes_to_read, self.block_size)
3408.6.1 by Eric Holmberg
Fix for Bug #215426 in which bzr can cause a MemoryError in socket.recv while
638
        self.assertEqual(from_file.get_max_read_size(), self.block_size)
639
        self.assertEqual(from_file.get_read_count(), 2)
640
641
        # finish reading the rest of the data
642
        num_bytes_to_read = self.test_data_len - to_file.tell()
4241.9.3 by Vincent Ladeuil
Fix two more test failures specific to OSX.
643
        osutils.pumpfile(from_file, to_file, num_bytes_to_read, self.block_size)
3408.6.1 by Eric Holmberg
Fix for Bug #215426 in which bzr can cause a MemoryError in socket.recv while
644
645
        # report error if the data wasn't equal (we only report the size due
646
        # to the length of the data)
647
        response_data = to_file.getvalue()
648
        if response_data != self.test_data:
649
            message = "Data not equal.  Expected %d bytes, received %d."
650
            self.fail(message % (len(response_data), self.test_data_len))
651
652
    def test_specified_size(self):
653
        """Request a transfer larger than the maximum block size and verify
654
        that the maximum read doesn't exceed the block_size."""
655
        # make sure test data is larger than max read size
656
        self.assertTrue(self.test_data_len > self.block_size)
657
658
        # retrieve data in blocks
4241.14.3 by Vincent Ladeuil
Cleanup imports.
659
        from_file = file_utils.FakeReadFile(self.test_data)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
660
        to_file = BytesIO()
4241.9.3 by Vincent Ladeuil
Fix two more test failures specific to OSX.
661
        osutils.pumpfile(from_file, to_file, self.test_data_len,
662
                         self.block_size)
3408.6.1 by Eric Holmberg
Fix for Bug #215426 in which bzr can cause a MemoryError in socket.recv while
663
664
        # verify read size was equal to the maximum read size
665
        self.assertTrue(from_file.get_max_read_size() > 0)
666
        self.assertEqual(from_file.get_max_read_size(), self.block_size)
667
        self.assertEqual(from_file.get_read_count(), 3)
668
669
        # report error if the data wasn't equal (we only report the size due
670
        # to the length of the data)
671
        response_data = to_file.getvalue()
672
        if response_data != self.test_data:
673
            message = "Data not equal.  Expected %d bytes, received %d."
674
            self.fail(message % (len(response_data), self.test_data_len))
675
676
    def test_to_eof(self):
677
        """Read to end-of-file and verify that the reads are not larger than
678
        the maximum read size."""
679
        # make sure test data is larger than max read size
680
        self.assertTrue(self.test_data_len > self.block_size)
681
682
        # retrieve data to EOF
4241.14.3 by Vincent Ladeuil
Cleanup imports.
683
        from_file = file_utils.FakeReadFile(self.test_data)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
684
        to_file = BytesIO()
4241.9.3 by Vincent Ladeuil
Fix two more test failures specific to OSX.
685
        osutils.pumpfile(from_file, to_file, -1, self.block_size)
3408.6.1 by Eric Holmberg
Fix for Bug #215426 in which bzr can cause a MemoryError in socket.recv while
686
687
        # verify read size was equal to the maximum read size
688
        self.assertEqual(from_file.get_max_read_size(), self.block_size)
689
        self.assertEqual(from_file.get_read_count(), 4)
690
691
        # report error if the data wasn't equal (we only report the size due
692
        # to the length of the data)
693
        response_data = to_file.getvalue()
694
        if response_data != self.test_data:
695
            message = "Data not equal.  Expected %d bytes, received %d."
696
            self.fail(message % (len(response_data), self.test_data_len))
697
698
    def test_defaults(self):
699
        """Verifies that the default arguments will read to EOF -- this
700
        test verifies that any existing usages of pumpfile will not be broken
701
        with this new version."""
702
        # retrieve data using default (old) pumpfile method
4241.14.3 by Vincent Ladeuil
Cleanup imports.
703
        from_file = file_utils.FakeReadFile(self.test_data)
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
704
        to_file = BytesIO()
4241.9.3 by Vincent Ladeuil
Fix two more test failures specific to OSX.
705
        osutils.pumpfile(from_file, to_file)
3408.6.1 by Eric Holmberg
Fix for Bug #215426 in which bzr can cause a MemoryError in socket.recv while
706
707
        # report error if the data wasn't equal (we only report the size due
708
        # to the length of the data)
709
        response_data = to_file.getvalue()
710
        if response_data != self.test_data:
711
            message = "Data not equal.  Expected %d bytes, received %d."
712
            self.fail(message % (len(response_data), self.test_data_len))
713
3956.2.1 by John Arbash Meinel
Add report_activity to osutils.pumpfile
714
    def test_report_activity(self):
715
        activity = []
716
        def log_activity(length, direction):
717
            activity.append((length, direction))
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
718
        from_file = BytesIO(self.test_data)
719
        to_file = BytesIO()
4241.9.3 by Vincent Ladeuil
Fix two more test failures specific to OSX.
720
        osutils.pumpfile(from_file, to_file, buff_size=500,
721
                         report_activity=log_activity, direction='read')
3956.2.1 by John Arbash Meinel
Add report_activity to osutils.pumpfile
722
        self.assertEqual([(500, 'read'), (500, 'read'), (500, 'read'),
723
                          (36, 'read')], activity)
724
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
725
        from_file = BytesIO(self.test_data)
726
        to_file = BytesIO()
3956.2.1 by John Arbash Meinel
Add report_activity to osutils.pumpfile
727
        del activity[:]
4241.9.3 by Vincent Ladeuil
Fix two more test failures specific to OSX.
728
        osutils.pumpfile(from_file, to_file, buff_size=500,
729
                         report_activity=log_activity, direction='write')
3956.2.1 by John Arbash Meinel
Add report_activity to osutils.pumpfile
730
        self.assertEqual([(500, 'write'), (500, 'write'), (500, 'write'),
731
                          (36, 'write')], activity)
732
733
        # And with a limited amount of data
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
734
        from_file = BytesIO(self.test_data)
735
        to_file = BytesIO()
3956.2.1 by John Arbash Meinel
Add report_activity to osutils.pumpfile
736
        del activity[:]
4241.9.3 by Vincent Ladeuil
Fix two more test failures specific to OSX.
737
        osutils.pumpfile(from_file, to_file, buff_size=500, read_length=1028,
738
                         report_activity=log_activity, direction='read')
3956.2.1 by John Arbash Meinel
Add report_activity to osutils.pumpfile
739
        self.assertEqual([(500, 'read'), (500, 'read'), (28, 'read')], activity)
740
741
3635.1.2 by Robert Collins
Add osutils.pump_string_file helper function.
742
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
743
class TestPumpStringFile(tests.TestCase):
3635.1.2 by Robert Collins
Add osutils.pump_string_file helper function.
744
745
    def test_empty(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
746
        output = BytesIO()
6632.1.2 by Martin
Fix tests for pump and send_all on Python 3
747
        osutils.pump_string_file(b"", output)
748
        self.assertEqual(b"", output.getvalue())
3635.1.2 by Robert Collins
Add osutils.pump_string_file helper function.
749
750
    def test_more_than_segment_size(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
751
        output = BytesIO()
6632.1.2 by Martin
Fix tests for pump and send_all on Python 3
752
        osutils.pump_string_file(b"123456789", output, 2)
753
        self.assertEqual(b"123456789", output.getvalue())
3635.1.2 by Robert Collins
Add osutils.pump_string_file helper function.
754
755
    def test_segment_size(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
756
        output = BytesIO()
6632.1.2 by Martin
Fix tests for pump and send_all on Python 3
757
        osutils.pump_string_file(b"12", output, 2)
758
        self.assertEqual(b"12", output.getvalue())
3635.1.2 by Robert Collins
Add osutils.pump_string_file helper function.
759
760
    def test_segment_size_multiple(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
761
        output = BytesIO()
6632.1.2 by Martin
Fix tests for pump and send_all on Python 3
762
        osutils.pump_string_file(b"1234", output, 2)
763
        self.assertEqual(b"1234", output.getvalue())
3635.1.2 by Robert Collins
Add osutils.pump_string_file helper function.
764
765
4555.2.1 by John Arbash Meinel
Fix bug #394227, osutils.relpath() could get into an infinite loop.
766
class TestRelpath(tests.TestCase):
767
768
    def test_simple_relpath(self):
769
        cwd = osutils.getcwd()
770
        subdir = cwd + '/subdir'
771
        self.assertEqual('subdir', osutils.relpath(cwd, subdir))
772
4555.2.3 by John Arbash Meinel
Fix a trivial bug that should have been caught earlier. :)
773
    def test_deep_relpath(self):
774
        cwd = osutils.getcwd()
775
        subdir = cwd + '/sub/subsubdir'
776
        self.assertEqual('sub/subsubdir', osutils.relpath(cwd, subdir))
777
4555.2.1 by John Arbash Meinel
Fix bug #394227, osutils.relpath() could get into an infinite loop.
778
    def test_not_relative(self):
779
        self.assertRaises(errors.PathNotChild,
780
                          osutils.relpath, 'C:/path', 'H:/path')
781
        self.assertRaises(errors.PathNotChild,
782
                          osutils.relpath, 'C:/', 'H:/path')
783
784
4241.14.3 by Vincent Ladeuil
Cleanup imports.
785
class TestSafeUnicode(tests.TestCase):
1534.3.1 by Robert Collins
* bzrlib.osutils.safe_unicode now exists to provide parameter coercion
786
787
    def test_from_ascii_string(self):
788
        self.assertEqual(u'foobar', osutils.safe_unicode('foobar'))
789
1534.3.2 by Robert Collins
An extra test for John.
790
    def test_from_unicode_string_ascii_contents(self):
1534.3.1 by Robert Collins
* bzrlib.osutils.safe_unicode now exists to provide parameter coercion
791
        self.assertEqual(u'bargam', osutils.safe_unicode(u'bargam'))
792
1534.3.2 by Robert Collins
An extra test for John.
793
    def test_from_unicode_string_unicode_contents(self):
794
        self.assertEqual(u'bargam\xae', osutils.safe_unicode(u'bargam\xae'))
795
1534.3.1 by Robert Collins
* bzrlib.osutils.safe_unicode now exists to provide parameter coercion
796
    def test_from_utf8_string(self):
797
        self.assertEqual(u'foo\xae', osutils.safe_unicode('foo\xc2\xae'))
798
799
    def test_bad_utf8_string(self):
4241.14.3 by Vincent Ladeuil
Cleanup imports.
800
        self.assertRaises(errors.BzrBadParameterNotUnicode,
1185.65.29 by Robert Collins
Implement final review suggestions.
801
                          osutils.safe_unicode,
802
                          '\xbb\xbb')
1666.1.6 by Robert Collins
Make knit the default format.
803
804
4241.14.3 by Vincent Ladeuil
Cleanup imports.
805
class TestSafeUtf8(tests.TestCase):
2249.5.8 by John Arbash Meinel
Add osutils.safe_utf8 and safe_revision_id for the new revision_id work.
806
807
    def test_from_ascii_string(self):
808
        f = 'foobar'
809
        self.assertEqual('foobar', osutils.safe_utf8(f))
810
811
    def test_from_unicode_string_ascii_contents(self):
812
        self.assertEqual('bargam', osutils.safe_utf8(u'bargam'))
813
814
    def test_from_unicode_string_unicode_contents(self):
815
        self.assertEqual('bargam\xc2\xae', osutils.safe_utf8(u'bargam\xae'))
816
817
    def test_from_utf8_string(self):
818
        self.assertEqual('foo\xc2\xae', osutils.safe_utf8('foo\xc2\xae'))
819
820
    def test_bad_utf8_string(self):
4241.14.3 by Vincent Ladeuil
Cleanup imports.
821
        self.assertRaises(errors.BzrBadParameterNotUnicode,
2249.5.8 by John Arbash Meinel
Add osutils.safe_utf8 and safe_revision_id for the new revision_id work.
822
                          osutils.safe_utf8, '\xbb\xbb')
823
824
4241.14.3 by Vincent Ladeuil
Cleanup imports.
825
class TestSafeRevisionId(tests.TestCase):
2249.5.8 by John Arbash Meinel
Add osutils.safe_utf8 and safe_revision_id for the new revision_id work.
826
827
    def test_from_ascii_string(self):
2858.2.1 by Martin Pool
Remove most calls to safe_file_id and safe_revision_id.
828
        # this shouldn't give a warning because it's getting an ascii string
2309.4.4 by John Arbash Meinel
Change what warnings are raised, and add tests that they are used.
829
        self.assertEqual('foobar', osutils.safe_revision_id('foobar'))
2249.5.8 by John Arbash Meinel
Add osutils.safe_utf8 and safe_revision_id for the new revision_id work.
830
831
    def test_from_unicode_string_ascii_contents(self):
6630.1.1 by Jelmer Vernooij
Remove deprecated functionality.
832
        self.assertRaises(TypeError,
833
                          osutils.safe_revision_id, u'bargam')
2249.5.8 by John Arbash Meinel
Add osutils.safe_utf8 and safe_revision_id for the new revision_id work.
834
835
    def test_from_unicode_string_unicode_contents(self):
6630.1.1 by Jelmer Vernooij
Remove deprecated functionality.
836
        self.assertRaises(TypeError,
837
                         osutils.safe_revision_id, u'bargam\xae')
2249.5.8 by John Arbash Meinel
Add osutils.safe_utf8 and safe_revision_id for the new revision_id work.
838
839
    def test_from_utf8_string(self):
840
        self.assertEqual('foo\xc2\xae',
841
                         osutils.safe_revision_id('foo\xc2\xae'))
842
2249.5.9 by John Arbash Meinel
Update WorkingTree to use safe_revision_id when appropriate
843
    def test_none(self):
844
        """Currently, None is a valid revision_id"""
845
        self.assertEqual(None, osutils.safe_revision_id(None))
846
2249.5.8 by John Arbash Meinel
Add osutils.safe_utf8 and safe_revision_id for the new revision_id work.
847
4241.14.3 by Vincent Ladeuil
Cleanup imports.
848
class TestSafeFileId(tests.TestCase):
2294.1.4 by John Arbash Meinel
Add safe_file_id as a helper in osutils.
849
850
    def test_from_ascii_string(self):
2309.4.4 by John Arbash Meinel
Change what warnings are raised, and add tests that they are used.
851
        self.assertEqual('foobar', osutils.safe_file_id('foobar'))
2294.1.4 by John Arbash Meinel
Add safe_file_id as a helper in osutils.
852
853
    def test_from_unicode_string_ascii_contents(self):
6630.1.1 by Jelmer Vernooij
Remove deprecated functionality.
854
        self.assertRaises(TypeError, osutils.safe_file_id, u'bargam')
2294.1.4 by John Arbash Meinel
Add safe_file_id as a helper in osutils.
855
856
    def test_from_unicode_string_unicode_contents(self):
6630.1.1 by Jelmer Vernooij
Remove deprecated functionality.
857
        self.assertRaises(TypeError,
858
                          osutils.safe_file_id, u'bargam\xae')
2294.1.4 by John Arbash Meinel
Add safe_file_id as a helper in osutils.
859
860
    def test_from_utf8_string(self):
861
        self.assertEqual('foo\xc2\xae',
862
                         osutils.safe_file_id('foo\xc2\xae'))
863
864
    def test_none(self):
865
        """Currently, None is a valid revision_id"""
866
        self.assertEqual(None, osutils.safe_file_id(None))
867
868
6437.73.1 by John Arbash Meinel
Fix bug #1047309. Treat a series of no-bytes-sent as a ECONNRESET failure.
869
class TestSendAll(tests.TestCase):
870
6437.74.4 by John Arbash Meinel
Since the code is in osutils, put the tests in there as well.
871
    def test_send_with_disconnected_socket(self):
872
        class DisconnectedSocket(object):
873
            def __init__(self, err):
874
                self.err = err
875
            def send(self, content):
876
                raise self.err
877
            def close(self):
878
                pass
879
        # All of these should be treated as ConnectionReset
880
        errs = []
881
        for err_cls in (IOError, socket.error):
882
            for errnum in osutils._end_of_stream_errors:
883
                errs.append(err_cls(errnum))
884
        for err in errs:
885
            sock = DisconnectedSocket(err)
886
            self.assertRaises(errors.ConnectionReset,
6632.1.2 by Martin
Fix tests for pump and send_all on Python 3
887
                osutils.send_all, sock, b'some more content')
6437.74.4 by John Arbash Meinel
Since the code is in osutils, put the tests in there as well.
888
6437.73.1 by John Arbash Meinel
Fix bug #1047309. Treat a series of no-bytes-sent as a ECONNRESET failure.
889
    def test_send_with_no_progress(self):
890
        # See https://bugs.launchpad.net/bzr/+bug/1047309
891
        # It seems that paramiko can get into a state where it doesn't error,
892
        # but it returns 0 bytes sent for requests over and over again.
893
        class NoSendingSocket(object):
894
            def __init__(self):
895
                self.call_count = 0
896
            def send(self, bytes):
897
                self.call_count += 1
898
                if self.call_count > 100:
899
                    # Prevent the test suite from hanging
900
                    raise RuntimeError('too many calls')
901
                return 0
902
        sock = NoSendingSocket()
6437.73.2 by John Arbash Meinel
simplify the fix. Sending 0 bytes seems to always indicate that we have a closed connection.
903
        self.assertRaises(errors.ConnectionReset,
6632.1.2 by Martin
Fix tests for pump and send_all on Python 3
904
                          osutils.send_all, sock, b'content')
6437.73.2 by John Arbash Meinel
simplify the fix. Sending 0 bytes seems to always indicate that we have a closed connection.
905
        self.assertEqual(1, sock.call_count)
6437.73.1 by John Arbash Meinel
Fix bug #1047309. Treat a series of no-bytes-sent as a ECONNRESET failure.
906
907
6015.39.1 by Florian Vichot
Add failing test to test normpath behaviour given a path starting with two leading slashes
908
class TestPosixFuncs(tests.TestCase):
909
    """Test that the posix version of normpath returns an appropriate path
910
       when used with 2 leading slashes."""
911
912
    def test_normpath(self):
6015.39.2 by Florian Vichot
Fixed an infinite loop when creating a repo at the root of the filesystem,
913
        self.assertEqual('/etc/shadow', osutils._posix_normpath('/etc/shadow'))
914
        self.assertEqual('/etc/shadow', osutils._posix_normpath('//etc/shadow'))
915
        self.assertEqual('/etc/shadow', osutils._posix_normpath('///etc/shadow'))
6015.39.1 by Florian Vichot
Add failing test to test normpath behaviour given a path starting with two leading slashes
916
917
4241.14.3 by Vincent Ladeuil
Cleanup imports.
918
class TestWin32Funcs(tests.TestCase):
919
    """Test that _win32 versions of os utilities return appropriate paths."""
1685.1.31 by John Arbash Meinel
Adding tests for the rest of the _win32 functions.
920
921
    def test_abspath(self):
6603.1.2 by Vincent Ladeuil
Skip the windows tests when not running on windows.
922
        self.requireFeature(features.win32_feature)
1685.1.31 by John Arbash Meinel
Adding tests for the rest of the _win32 functions.
923
        self.assertEqual('C:/foo', osutils._win32_abspath('C:\\foo'))
924
        self.assertEqual('C:/foo', osutils._win32_abspath('C:/foo'))
2279.4.1 by Alexander Belchenko
Reimplementation of ntpath.abspath in Python for Windows98: unicode safe, UNC path safe
925
        self.assertEqual('//HOST/path', osutils._win32_abspath(r'\\HOST\path'))
926
        self.assertEqual('//HOST/path', osutils._win32_abspath('//HOST/path'))
1685.1.31 by John Arbash Meinel
Adding tests for the rest of the _win32 functions.
927
928
    def test_realpath(self):
929
        self.assertEqual('C:/foo', osutils._win32_realpath('C:\\foo'))
930
        self.assertEqual('C:/foo', osutils._win32_realpath('C:/foo'))
931
932
    def test_pathjoin(self):
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
933
        self.assertEqual('path/to/foo',
934
                         osutils._win32_pathjoin('path', 'to', 'foo'))
935
        self.assertEqual('C:/foo',
936
                         osutils._win32_pathjoin('path\\to', 'C:\\foo'))
937
        self.assertEqual('C:/foo',
938
                         osutils._win32_pathjoin('path/to', 'C:/foo'))
939
        self.assertEqual('path/to/foo',
940
                         osutils._win32_pathjoin('path/to/', 'foo'))
6592.1.2 by Vincent Ladeuil
Late bugfix in python 2.7.6, only tests are affected.
941
942
    def test_pathjoin_late_bugfix(self):
943
        if sys.version_info < (2, 7, 6):
944
            expected = '/foo'
945
        else:
946
            expected = 'C:/foo'
947
        self.assertEqual(expected,
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
948
                         osutils._win32_pathjoin('C:/path/to/', '/foo'))
6592.1.2 by Vincent Ladeuil
Late bugfix in python 2.7.6, only tests are affected.
949
        self.assertEqual(expected,
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
950
                         osutils._win32_pathjoin('C:\\path\\to\\', '\\foo'))
1685.1.31 by John Arbash Meinel
Adding tests for the rest of the _win32 functions.
951
952
    def test_normpath(self):
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
953
        self.assertEqual('path/to/foo',
954
                         osutils._win32_normpath(r'path\\from\..\to\.\foo'))
955
        self.assertEqual('path/to/foo',
956
                         osutils._win32_normpath('path//from/../to/./foo'))
1685.1.31 by John Arbash Meinel
Adding tests for the rest of the _win32 functions.
957
958
    def test_getcwd(self):
1711.5.2 by John Arbash Meinel
win32 likes to return lowercase drive letters sometimes, and uppercase at other times. normalize this
959
        cwd = osutils._win32_getcwd()
6619.3.26 by Martin
Fix fallout from 2to3 getcwdu transformation and other test uses
960
        os_cwd = osutils._getcwd()
1711.5.2 by John Arbash Meinel
win32 likes to return lowercase drive letters sometimes, and uppercase at other times. normalize this
961
        self.assertEqual(os_cwd[1:].replace('\\', '/'), cwd[1:])
962
        # win32 is inconsistent whether it returns lower or upper case
963
        # and even if it was consistent the user might type the other
964
        # so we force it to uppercase
965
        # running python.exe under cmd.exe return capital C:\\
966
        # running win32 python inside a cygwin shell returns lowercase
967
        self.assertEqual(os_cwd[0].upper(), cwd[0])
968
969
    def test_fixdrive(self):
970
        self.assertEqual('H:/foo', osutils._win32_fixdrive('h:/foo'))
971
        self.assertEqual('H:/foo', osutils._win32_fixdrive('H:/foo'))
972
        self.assertEqual('C:\\foo', osutils._win32_fixdrive('c:\\foo'))
1685.1.31 by John Arbash Meinel
Adding tests for the rest of the _win32 functions.
973
2279.4.1 by Alexander Belchenko
Reimplementation of ntpath.abspath in Python for Windows98: unicode safe, UNC path safe
974
    def test_win98_abspath(self):
6603.1.2 by Vincent Ladeuil
Skip the windows tests when not running on windows.
975
        self.requireFeature(features.win32_feature)
2279.4.1 by Alexander Belchenko
Reimplementation of ntpath.abspath in Python for Windows98: unicode safe, UNC path safe
976
        # absolute path
977
        self.assertEqual('C:/foo', osutils._win98_abspath('C:\\foo'))
978
        self.assertEqual('C:/foo', osutils._win98_abspath('C:/foo'))
979
        # UNC path
980
        self.assertEqual('//HOST/path', osutils._win98_abspath(r'\\HOST\path'))
981
        self.assertEqual('//HOST/path', osutils._win98_abspath('//HOST/path'))
982
        # relative path
983
        cwd = osutils.getcwd().rstrip('/')
5273.1.2 by Vincent Ladeuil
Cleanup imports in osutils.py.
984
        drive = osutils.ntpath.splitdrive(cwd)[0]
2279.4.1 by Alexander Belchenko
Reimplementation of ntpath.abspath in Python for Windows98: unicode safe, UNC path safe
985
        self.assertEqual(cwd+'/path', osutils._win98_abspath('path'))
986
        self.assertEqual(drive+'/path', osutils._win98_abspath('/path'))
987
        # unicode path
988
        u = u'\u1234'
989
        self.assertEqual(cwd+'/'+u, osutils._win98_abspath(u))
990
1685.1.31 by John Arbash Meinel
Adding tests for the rest of the _win32 functions.
991
4241.14.3 by Vincent Ladeuil
Cleanup imports.
992
class TestWin32FuncsDirs(tests.TestCaseInTempDir):
1685.1.31 by John Arbash Meinel
Adding tests for the rest of the _win32 functions.
993
    """Test win32 functions that create files."""
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
994
1685.1.31 by John Arbash Meinel
Adding tests for the rest of the _win32 functions.
995
    def test_getcwd(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
996
        self.requireFeature(features.UnicodeFilenameFeature)
4241.14.5 by Vincent Ladeuil
Some more cleanup (without typo).
997
        os.mkdir(u'mu-\xb5')
1830.3.9 by John Arbash Meinel
Use a directory name that doesn't get messed up on Mac for getcwd() test.
998
        os.chdir(u'mu-\xb5')
1685.1.31 by John Arbash Meinel
Adding tests for the rest of the _win32 functions.
999
        # TODO: jam 20060427 This will probably fail on Mac OSX because
1000
        #       it will change the normalization of B\xe5gfors
1001
        #       Consider using a different unicode character, or make
1002
        #       osutils.getcwd() renormalize the path.
1830.3.9 by John Arbash Meinel
Use a directory name that doesn't get messed up on Mac for getcwd() test.
1003
        self.assertEndsWith(osutils._win32_getcwd(), u'mu-\xb5')
1685.1.31 by John Arbash Meinel
Adding tests for the rest of the _win32 functions.
1004
2825.7.1 by Robert Collins
* Partial commits are now approximately 40% faster by walking over the
1005
    def test_minimum_path_selection(self):
1006
        self.assertEqual(set(),
1007
            osutils.minimum_path_selection([]))
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
1008
        self.assertEqual({'a'},
4325.3.7 by Johan Walles
Style fixes for minimum_path_selection().
1009
            osutils.minimum_path_selection(['a']))
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
1010
        self.assertEqual({'a', 'b'},
2825.7.1 by Robert Collins
* Partial commits are now approximately 40% faster by walking over the
1011
            osutils.minimum_path_selection(['a', 'b']))
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
1012
        self.assertEqual({'a/', 'b'},
2825.7.1 by Robert Collins
* Partial commits are now approximately 40% faster by walking over the
1013
            osutils.minimum_path_selection(['a/', 'b']))
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
1014
        self.assertEqual({'a/', 'b'},
2825.7.1 by Robert Collins
* Partial commits are now approximately 40% faster by walking over the
1015
            osutils.minimum_path_selection(['a/c', 'a/', 'b']))
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
1016
        self.assertEqual({'a-b', 'a', 'a0b'},
4325.3.3 by Johan Walles
Add unit test and fix for minimum_path_selection() vs directory names with
1017
            osutils.minimum_path_selection(['a-b', 'a/b', 'a0b', 'a']))
2825.7.1 by Robert Collins
* Partial commits are now approximately 40% faster by walking over the
1018
1685.1.31 by John Arbash Meinel
Adding tests for the rest of the _win32 functions.
1019
    def test_mkdtemp(self):
1020
        tmpdir = osutils._win32_mkdtemp(dir='.')
1021
        self.assertFalse('\\' in tmpdir)
1022
1023
    def test_rename(self):
1024
        a = open('a', 'wb')
1025
        a.write('foo\n')
1026
        a.close()
1027
        b = open('b', 'wb')
1028
        b.write('baz\n')
1029
        b.close()
1030
1031
        osutils._win32_rename('b', 'a')
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
1032
        self.assertPathExists('a')
1033
        self.assertPathDoesNotExist('b')
1685.1.31 by John Arbash Meinel
Adding tests for the rest of the _win32 functions.
1034
        self.assertFileEqual('baz\n', 'a')
1035
1711.7.6 by John Arbash Meinel
Change _win32_rename() so that it raises ENOENT *before* it tries any renaming.
1036
    def test_rename_missing_file(self):
1037
        a = open('a', 'wb')
1038
        a.write('foo\n')
1039
        a.close()
1040
1041
        try:
1042
            osutils._win32_rename('b', 'a')
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
1043
        except (IOError, OSError) as e:
1711.7.6 by John Arbash Meinel
Change _win32_rename() so that it raises ENOENT *before* it tries any renaming.
1044
            self.assertEqual(errno.ENOENT, e.errno)
1045
        self.assertFileEqual('foo\n', 'a')
1046
1047
    def test_rename_missing_dir(self):
1048
        os.mkdir('a')
1049
        try:
1050
            osutils._win32_rename('b', 'a')
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
1051
        except (IOError, OSError) as e:
1711.7.6 by John Arbash Meinel
Change _win32_rename() so that it raises ENOENT *before* it tries any renaming.
1052
            self.assertEqual(errno.ENOENT, e.errno)
1053
1054
    def test_rename_current_dir(self):
1055
        os.mkdir('a')
1056
        os.chdir('a')
1057
        # You can't rename the working directory
1058
        # doing rename non-existant . usually
1059
        # just raises ENOENT, since non-existant
1060
        # doesn't exist.
1061
        try:
1062
            osutils._win32_rename('b', '.')
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
1063
        except (IOError, OSError) as e:
1711.7.6 by John Arbash Meinel
Change _win32_rename() so that it raises ENOENT *before* it tries any renaming.
1064
            self.assertEqual(errno.ENOENT, e.errno)
1065
1996.3.14 by John Arbash Meinel
lazy_import osutils and sign_my_commits
1066
    def test_splitpath(self):
1067
        def check(expected, path):
1068
            self.assertEqual(expected, osutils.splitpath(path))
1069
1070
        check(['a'], 'a')
1071
        check(['a', 'b'], 'a/b')
1072
        check(['a', 'b'], 'a/./b')
1073
        check(['a', '.b'], 'a/.b')
1074
        check(['a', '.b'], 'a\\.b')
1075
1076
        self.assertRaises(errors.BzrError, osutils.splitpath, 'a/../b')
1077
1685.1.31 by John Arbash Meinel
Adding tests for the rest of the _win32 functions.
1078
4370.1.1 by Ian Clatworthy
add osutils.parent_directories() API
1079
class TestParentDirectories(tests.TestCaseInTempDir):
1080
    """Test osutils.parent_directories()"""
1081
1082
    def test_parent_directories(self):
1083
        self.assertEqual([], osutils.parent_directories('a'))
1084
        self.assertEqual(['a'], osutils.parent_directories('a/b'))
1085
        self.assertEqual(['a/b', 'a'], osutils.parent_directories('a/b/c'))
1086
1087
4241.14.3 by Vincent Ladeuil
Cleanup imports.
1088
class TestMacFuncsDirs(tests.TestCaseInTempDir):
1830.3.11 by John Arbash Meinel
Create a mac version of 'getcwd()' which normalizes the path.
1089
    """Test mac special functions that require directories."""
1090
1091
    def test_getcwd(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1092
        self.requireFeature(features.UnicodeFilenameFeature)
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
1093
        os.mkdir(u'B\xe5gfors')
1830.3.11 by John Arbash Meinel
Create a mac version of 'getcwd()' which normalizes the path.
1094
        os.chdir(u'B\xe5gfors')
1095
        self.assertEndsWith(osutils._mac_getcwd(), u'B\xe5gfors')
1096
1097
    def test_getcwd_nonnorm(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1098
        self.requireFeature(features.UnicodeFilenameFeature)
1830.3.11 by John Arbash Meinel
Create a mac version of 'getcwd()' which normalizes the path.
1099
        # Test that _mac_getcwd() will normalize this path
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
1100
        os.mkdir(u'Ba\u030agfors')
1830.3.11 by John Arbash Meinel
Create a mac version of 'getcwd()' which normalizes the path.
1101
        os.chdir(u'Ba\u030agfors')
1102
        self.assertEndsWith(osutils._mac_getcwd(), u'B\xe5gfors')
1103
1996.3.14 by John Arbash Meinel
lazy_import osutils and sign_my_commits
1104
4241.14.3 by Vincent Ladeuil
Cleanup imports.
1105
class TestChunksToLines(tests.TestCase):
3890.2.4 by John Arbash Meinel
Add a new function that can convert 'chunks' format to a 'lines' format.
1106
3890.2.8 by John Arbash Meinel
Move everything into properly parameterized tests.
1107
    def test_smoketest(self):
1108
        self.assertEqual(['foo\n', 'bar\n', 'baz\n'],
1109
                         osutils.chunks_to_lines(['foo\nbar', '\nbaz\n']))
1110
        self.assertEqual(['foo\n', 'bar\n', 'baz\n'],
1111
                         osutils.chunks_to_lines(['foo\n', 'bar\n', 'baz\n']))
1112
3734.2.21 by Vincent Ladeuil
Give test a better name.
1113
    def test_osutils_binding(self):
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
1114
        from . import test__chunks_to_lines
4913.2.26 by John Arbash Meinel
A bunch of osutils tests depended on features being available.
1115
        if test__chunks_to_lines.compiled_chunkstolines_feature.available():
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
1116
            from .._chunks_to_lines_pyx import chunks_to_lines
3890.2.8 by John Arbash Meinel
Move everything into properly parameterized tests.
1117
        else:
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
1118
            from .._chunks_to_lines_py import chunks_to_lines
3890.2.8 by John Arbash Meinel
Move everything into properly parameterized tests.
1119
        self.assertIs(chunks_to_lines, osutils.chunks_to_lines)
3890.2.5 by John Arbash Meinel
More tests for edge cases.
1120
3890.2.4 by John Arbash Meinel
Add a new function that can convert 'chunks' format to a 'lines' format.
1121
4241.14.3 by Vincent Ladeuil
Cleanup imports.
1122
class TestSplitLines(tests.TestCase):
1666.1.6 by Robert Collins
Make knit the default format.
1123
1124
    def test_split_unicode(self):
1125
        self.assertEqual([u'foo\n', u'bar\xae'],
1126
                         osutils.split_lines(u'foo\nbar\xae'))
1127
        self.assertEqual([u'foo\n', u'bar\xae\n'],
1128
                         osutils.split_lines(u'foo\nbar\xae\n'))
1129
1130
    def test_split_with_carriage_returns(self):
1131
        self.assertEqual(['foo\rbar\n'],
1132
                         osutils.split_lines('foo\rbar\n'))
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
1133
1134
4241.14.3 by Vincent Ladeuil
Cleanup imports.
1135
class TestWalkDirs(tests.TestCaseInTempDir):
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
1136
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
1137
    def assertExpectedBlocks(self, expected, result):
1138
        self.assertEqual(expected,
1139
                         [(dirinfo, [line[0:3] for line in block])
1140
                          for dirinfo, block in result])
1141
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
1142
    def test_walkdirs(self):
1143
        tree = [
1144
            '.bzr',
1145
            '0file',
1146
            '1dir/',
1147
            '1dir/0file',
1148
            '1dir/1dir/',
1149
            '2file'
1150
            ]
1151
        self.build_tree(tree)
1152
        expected_dirblocks = [
1897.1.1 by Robert Collins
Add some useful summary data to osutils.walkdirs output.
1153
                (('', '.'),
1154
                 [('0file', '0file', 'file'),
1155
                  ('1dir', '1dir', 'directory'),
1156
                  ('2file', '2file', 'file'),
1157
                 ]
1158
                ),
1159
                (('1dir', './1dir'),
1160
                 [('1dir/0file', '0file', 'file'),
1161
                  ('1dir/1dir', '1dir', 'directory'),
1162
                 ]
1163
                ),
1164
                (('1dir/1dir', './1dir/1dir'),
1165
                 [
1166
                 ]
1167
                ),
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
1168
            ]
1169
        result = []
1170
        found_bzrdir = False
1897.1.1 by Robert Collins
Add some useful summary data to osutils.walkdirs output.
1171
        for dirdetail, dirblock in osutils.walkdirs('.'):
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
1172
            if len(dirblock) and dirblock[0][1] == '.bzr':
1173
                # this tests the filtering of selected paths
1174
                found_bzrdir = True
1175
                del dirblock[0]
1897.1.1 by Robert Collins
Add some useful summary data to osutils.walkdirs output.
1176
            result.append((dirdetail, dirblock))
1753.1.1 by Robert Collins
(rbc, jam, mbp)Add bzrlib.osutils.walkdirs, an optimised walk-and-stat routine.
1177
1178
        self.assertTrue(found_bzrdir)
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
1179
        self.assertExpectedBlocks(expected_dirblocks, result)
1757.2.8 by Robert Collins
Teach walkdirs to walk a subdir of a tree.
1180
        # you can search a subdir only, with a supplied prefix.
1181
        result = []
1897.1.1 by Robert Collins
Add some useful summary data to osutils.walkdirs output.
1182
        for dirblock in osutils.walkdirs('./1dir', '1dir'):
1757.2.8 by Robert Collins
Teach walkdirs to walk a subdir of a tree.
1183
            result.append(dirblock)
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
1184
        self.assertExpectedBlocks(expected_dirblocks[1:], result)
1757.2.8 by Robert Collins
Teach walkdirs to walk a subdir of a tree.
1185
4095.1.3 by Martin Pool
Add test for failures inside pyrex readdir
1186
    def test_walkdirs_os_error(self):
5243.1.2 by Martin
Point launchpad links in comments at production server rather than edge
1187
        # <https://bugs.launchpad.net/bzr/+bug/338653>
4095.1.3 by Martin Pool
Add test for failures inside pyrex readdir
1188
        # Pyrex readdir didn't raise useful messages if it had an error
1189
        # reading the directory
1190
        if sys.platform == 'win32':
1191
            raise tests.TestNotApplicable(
1192
                "readdir IOError not tested on win32")
4797.70.1 by Vincent Ladeuil
Skip chmodbits dependent tests when running as root
1193
        self.requireFeature(features.not_running_as_root)
4095.1.3 by Martin Pool
Add test for failures inside pyrex readdir
1194
        os.mkdir("test-unreadable")
1195
        os.chmod("test-unreadable", 0000)
1196
        # must chmod it back so that it can be removed
6619.3.14 by Jelmer Vernooij
Convert some octal numbers to new notations.
1197
        self.addCleanup(os.chmod, "test-unreadable", 0o700)
4095.1.3 by Martin Pool
Add test for failures inside pyrex readdir
1198
        # The error is not raised until the generator is actually evaluated.
1199
        # (It would be ok if it happened earlier but at the moment it
1200
        # doesn't.)
4133.1.1 by Vincent Ladeuil
Fix bzrlib.tests.test_osutils.TestWalkDirs.test_walkdirs_os_error
1201
        e = self.assertRaises(OSError, list, osutils._walkdirs_utf8("."))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1202
        self.assertEqual('./test-unreadable', e.filename)
1203
        self.assertEqual(errno.EACCES, e.errno)
4133.1.2 by Vincent Ladeuil
Fixed as per Martin's remark about the intent of the test :-}
1204
        # Ensure the message contains the file name
1205
        self.assertContainsRe(str(e), "\./test-unreadable")
4095.1.3 by Martin Pool
Add test for failures inside pyrex readdir
1206
5279.2.5 by Eric Moritz
added a test to make sure that BadFilenameEncoding is thrown
1207
1208
    def test_walkdirs_encoding_error(self):
1209
        # <https://bugs.launchpad.net/bzr/+bug/488519>
1210
        # walkdirs didn't raise a useful message when the filenames
5279.2.8 by Eric Moritz
1. used os.rename instead of shutil.move
1211
        # are not using the filesystem's encoding
1212
5279.2.11 by Eric Moritz
Utilized the ByteStringNamedFilesystem per Martin Pool's request
1213
        # require a bytestring based filesystem
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1214
        self.requireFeature(features.ByteStringNamedFilesystem)
5279.2.8 by Eric Moritz
1. used os.rename instead of shutil.move
1215
5279.2.5 by Eric Moritz
added a test to make sure that BadFilenameEncoding is thrown
1216
        tree = [
1217
            '.bzr',
1218
            '0file',
1219
            '1dir/',
1220
            '1dir/0file',
1221
            '1dir/1dir/',
1222
            '1file'
1223
            ]
1224
1225
        self.build_tree(tree)
1226
1227
        # rename the 1file to a latin-1 filename
5279.2.8 by Eric Moritz
1. used os.rename instead of shutil.move
1228
        os.rename("./1file", "\xe8file")
5551.3.1 by Martin
Skip walkdirs invalid encoding test on filesystems that don't preserve arbitrary bytes
1229
        if "\xe8file" not in os.listdir("."):
6622.4.1 by Martin
Use skipTest rather than deprecated skip method
1230
            self.skipTest("Lack filesystem that preserves arbitrary bytes")
5279.2.5 by Eric Moritz
added a test to make sure that BadFilenameEncoding is thrown
1231
1232
        self._save_platform_info()
1233
        win32utils.winver = None # Avoid the win32 detection code
1234
        osutils._fs_enc = 'UTF-8'
1235
1236
        # this should raise on error
1237
        def attempt():
1238
            for dirdetail, dirblock in osutils.walkdirs('.'):
1239
                pass
1240
1241
        self.assertRaises(errors.BadFilenameEncoding, attempt)
1242
2255.7.27 by John Arbash Meinel
Add a _walkdirs_utf8 which returns utf8 paths instead of Unicode. Approx 20% faster in walking utf8 filesystems
1243
    def test__walkdirs_utf8(self):
1244
        tree = [
1245
            '.bzr',
1246
            '0file',
1247
            '1dir/',
1248
            '1dir/0file',
1249
            '1dir/1dir/',
1250
            '2file'
1251
            ]
1252
        self.build_tree(tree)
1253
        expected_dirblocks = [
1254
                (('', '.'),
1255
                 [('0file', '0file', 'file'),
1256
                  ('1dir', '1dir', 'directory'),
1257
                  ('2file', '2file', 'file'),
1258
                 ]
1259
                ),
1260
                (('1dir', './1dir'),
1261
                 [('1dir/0file', '0file', 'file'),
1262
                  ('1dir/1dir', '1dir', 'directory'),
1263
                 ]
1264
                ),
1265
                (('1dir/1dir', './1dir/1dir'),
1266
                 [
1267
                 ]
1268
                ),
1269
            ]
1270
        result = []
1271
        found_bzrdir = False
1272
        for dirdetail, dirblock in osutils._walkdirs_utf8('.'):
1273
            if len(dirblock) and dirblock[0][1] == '.bzr':
1274
                # this tests the filtering of selected paths
1275
                found_bzrdir = True
1276
                del dirblock[0]
1277
            result.append((dirdetail, dirblock))
1278
1279
        self.assertTrue(found_bzrdir)
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
1280
        self.assertExpectedBlocks(expected_dirblocks, result)
1281
2255.7.27 by John Arbash Meinel
Add a _walkdirs_utf8 which returns utf8 paths instead of Unicode. Approx 20% faster in walking utf8 filesystems
1282
        # you can search a subdir only, with a supplied prefix.
1283
        result = []
1284
        for dirblock in osutils.walkdirs('./1dir', '1dir'):
1285
            result.append(dirblock)
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
1286
        self.assertExpectedBlocks(expected_dirblocks[1:], result)
2255.7.27 by John Arbash Meinel
Add a _walkdirs_utf8 which returns utf8 paths instead of Unicode. Approx 20% faster in walking utf8 filesystems
1287
2255.7.32 by John Arbash Meinel
Add tests that the walkdirs variants work on unicode paths.
1288
    def _filter_out_stat(self, result):
1289
        """Filter out the stat value from the walkdirs result"""
1290
        for dirdetail, dirblock in result:
1291
            new_dirblock = []
1292
            for info in dirblock:
1293
                # Ignore info[3] which is the stat
1294
                new_dirblock.append((info[0], info[1], info[2], info[4]))
1295
            dirblock[:] = new_dirblock
1296
3557.2.3 by John Arbash Meinel
Change the logic for selecting a real _walkdirs_utf8 implementation,
1297
    def _save_platform_info(self):
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
1298
        self.overrideAttr(win32utils, 'winver')
1299
        self.overrideAttr(osutils, '_fs_enc')
1300
        self.overrideAttr(osutils, '_selected_dir_reader')
3557.2.3 by John Arbash Meinel
Change the logic for selecting a real _walkdirs_utf8 implementation,
1301
4241.14.5 by Vincent Ladeuil
Some more cleanup (without typo).
1302
    def assertDirReaderIs(self, expected):
3557.2.4 by John Arbash Meinel
Cleanup the tests a bit, and add a test that we downgrade if os.name isn't 'nt'
1303
        """Assert the right implementation for _walkdirs_utf8 is chosen."""
1304
        # Force it to redetect
3696.3.1 by Robert Collins
Refactor bzrlib.osutils._walkdirs_utf8 to aid API migration in future.
1305
        osutils._selected_dir_reader = None
3557.2.4 by John Arbash Meinel
Cleanup the tests a bit, and add a test that we downgrade if os.name isn't 'nt'
1306
        # Nothing to list, but should still trigger the selection logic
3557.2.5 by John Arbash Meinel
Test that the empty-directory logic for all _walkdirs implementations is correct.
1307
        self.assertEqual([(('', '.'), [])], list(osutils._walkdirs_utf8('.')))
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
1308
        self.assertIsInstance(osutils._selected_dir_reader, expected)
3557.2.4 by John Arbash Meinel
Cleanup the tests a bit, and add a test that we downgrade if os.name isn't 'nt'
1309
1310
    def test_force_walkdirs_utf8_fs_utf8(self):
3696.3.5 by Robert Collins
Streamline _walkdirs_utf8 for utf8 file systems, reducing time to traverse a mozilla tree from 1s to .6 seconds. (Robert Collins)
1311
        self.requireFeature(UTF8DirReaderFeature)
3557.2.3 by John Arbash Meinel
Change the logic for selecting a real _walkdirs_utf8 implementation,
1312
        self._save_platform_info()
3557.2.6 by John Arbash Meinel
Switch from os.name to bzrlib.win32utils.winver.
1313
        win32utils.winver = None # Avoid the win32 detection code
6352.3.9 by Martin Packman
Fix TestWalkDirs tests now value of _fs_enc is stricter
1314
        osutils._fs_enc = 'utf-8'
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1315
        self.assertDirReaderIs(
1316
            UTF8DirReaderFeature.module.UTF8DirReader)
3557.2.3 by John Arbash Meinel
Change the logic for selecting a real _walkdirs_utf8 implementation,
1317
3557.2.4 by John Arbash Meinel
Cleanup the tests a bit, and add a test that we downgrade if os.name isn't 'nt'
1318
    def test_force_walkdirs_utf8_fs_ascii(self):
3696.3.5 by Robert Collins
Streamline _walkdirs_utf8 for utf8 file systems, reducing time to traverse a mozilla tree from 1s to .6 seconds. (Robert Collins)
1319
        self.requireFeature(UTF8DirReaderFeature)
3557.2.3 by John Arbash Meinel
Change the logic for selecting a real _walkdirs_utf8 implementation,
1320
        self._save_platform_info()
3557.2.6 by John Arbash Meinel
Switch from os.name to bzrlib.win32utils.winver.
1321
        win32utils.winver = None # Avoid the win32 detection code
6352.3.9 by Martin Packman
Fix TestWalkDirs tests now value of _fs_enc is stricter
1322
        osutils._fs_enc = 'ascii'
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1323
        self.assertDirReaderIs(
1324
            UTF8DirReaderFeature.module.UTF8DirReader)
3557.2.3 by John Arbash Meinel
Change the logic for selecting a real _walkdirs_utf8 implementation,
1325
3557.2.4 by John Arbash Meinel
Cleanup the tests a bit, and add a test that we downgrade if os.name isn't 'nt'
1326
    def test_force_walkdirs_utf8_fs_latin1(self):
3557.2.3 by John Arbash Meinel
Change the logic for selecting a real _walkdirs_utf8 implementation,
1327
        self._save_platform_info()
3557.2.6 by John Arbash Meinel
Switch from os.name to bzrlib.win32utils.winver.
1328
        win32utils.winver = None # Avoid the win32 detection code
6352.3.9 by Martin Packman
Fix TestWalkDirs tests now value of _fs_enc is stricter
1329
        osutils._fs_enc = 'iso-8859-1'
4241.14.5 by Vincent Ladeuil
Some more cleanup (without typo).
1330
        self.assertDirReaderIs(osutils.UnicodeDirReader)
3557.2.4 by John Arbash Meinel
Cleanup the tests a bit, and add a test that we downgrade if os.name isn't 'nt'
1331
1332
    def test_force_walkdirs_utf8_nt(self):
3696.3.1 by Robert Collins
Refactor bzrlib.osutils._walkdirs_utf8 to aid API migration in future.
1333
        # Disabled because the thunk of the whole walkdirs api is disabled.
4913.2.26 by John Arbash Meinel
A bunch of osutils tests depended on features being available.
1334
        self.requireFeature(test__walkdirs_win32.win32_readdir_feature)
3557.2.4 by John Arbash Meinel
Cleanup the tests a bit, and add a test that we downgrade if os.name isn't 'nt'
1335
        self._save_platform_info()
3557.2.6 by John Arbash Meinel
Switch from os.name to bzrlib.win32utils.winver.
1336
        win32utils.winver = 'Windows NT'
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
1337
        from .._walkdirs_win32 import Win32ReadDir
4241.14.5 by Vincent Ladeuil
Some more cleanup (without typo).
1338
        self.assertDirReaderIs(Win32ReadDir)
3557.2.4 by John Arbash Meinel
Cleanup the tests a bit, and add a test that we downgrade if os.name isn't 'nt'
1339
3696.3.1 by Robert Collins
Refactor bzrlib.osutils._walkdirs_utf8 to aid API migration in future.
1340
    def test_force_walkdirs_utf8_98(self):
4913.2.26 by John Arbash Meinel
A bunch of osutils tests depended on features being available.
1341
        self.requireFeature(test__walkdirs_win32.win32_readdir_feature)
3557.2.4 by John Arbash Meinel
Cleanup the tests a bit, and add a test that we downgrade if os.name isn't 'nt'
1342
        self._save_platform_info()
3557.2.6 by John Arbash Meinel
Switch from os.name to bzrlib.win32utils.winver.
1343
        win32utils.winver = 'Windows 98'
4241.14.5 by Vincent Ladeuil
Some more cleanup (without typo).
1344
        self.assertDirReaderIs(osutils.UnicodeDirReader)
3557.2.3 by John Arbash Meinel
Change the logic for selecting a real _walkdirs_utf8 implementation,
1345
2255.7.32 by John Arbash Meinel
Add tests that the walkdirs variants work on unicode paths.
1346
    def test_unicode_walkdirs(self):
1347
        """Walkdirs should always return unicode paths."""
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1348
        self.requireFeature(features.UnicodeFilenameFeature)
2255.7.32 by John Arbash Meinel
Add tests that the walkdirs variants work on unicode paths.
1349
        name0 = u'0file-\xb6'
1350
        name1 = u'1dir-\u062c\u0648'
1351
        name2 = u'2file-\u0633'
1352
        tree = [
1353
            name0,
1354
            name1 + '/',
1355
            name1 + '/' + name0,
1356
            name1 + '/' + name1 + '/',
1357
            name2,
1358
            ]
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
1359
        self.build_tree(tree)
2255.7.32 by John Arbash Meinel
Add tests that the walkdirs variants work on unicode paths.
1360
        expected_dirblocks = [
1361
                ((u'', u'.'),
1362
                 [(name0, name0, 'file', './' + name0),
1363
                  (name1, name1, 'directory', './' + name1),
1364
                  (name2, name2, 'file', './' + name2),
1365
                 ]
1366
                ),
1367
                ((name1, './' + name1),
1368
                 [(name1 + '/' + name0, name0, 'file', './' + name1
1369
                                                        + '/' + name0),
1370
                  (name1 + '/' + name1, name1, 'directory', './' + name1
1371
                                                            + '/' + name1),
1372
                 ]
1373
                ),
1374
                ((name1 + '/' + name1, './' + name1 + '/' + name1),
1375
                 [
1376
                 ]
1377
                ),
1378
            ]
1379
        result = list(osutils.walkdirs('.'))
1380
        self._filter_out_stat(result)
1381
        self.assertEqual(expected_dirblocks, result)
1382
        result = list(osutils.walkdirs(u'./'+name1, name1))
1383
        self._filter_out_stat(result)
1384
        self.assertEqual(expected_dirblocks[1:], result)
1385
1386
    def test_unicode__walkdirs_utf8(self):
1387
        """Walkdirs_utf8 should always return utf8 paths.
1388
1389
        The abspath portion might be in unicode or utf-8
1390
        """
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1391
        self.requireFeature(features.UnicodeFilenameFeature)
2255.7.32 by John Arbash Meinel
Add tests that the walkdirs variants work on unicode paths.
1392
        name0 = u'0file-\xb6'
1393
        name1 = u'1dir-\u062c\u0648'
1394
        name2 = u'2file-\u0633'
1395
        tree = [
1396
            name0,
1397
            name1 + '/',
1398
            name1 + '/' + name0,
1399
            name1 + '/' + name1 + '/',
1400
            name2,
1401
            ]
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
1402
        self.build_tree(tree)
2255.7.32 by John Arbash Meinel
Add tests that the walkdirs variants work on unicode paths.
1403
        name0 = name0.encode('utf8')
1404
        name1 = name1.encode('utf8')
1405
        name2 = name2.encode('utf8')
1406
1407
        expected_dirblocks = [
1408
                (('', '.'),
1409
                 [(name0, name0, 'file', './' + name0),
1410
                  (name1, name1, 'directory', './' + name1),
1411
                  (name2, name2, 'file', './' + name2),
1412
                 ]
1413
                ),
1414
                ((name1, './' + name1),
1415
                 [(name1 + '/' + name0, name0, 'file', './' + name1
1416
                                                        + '/' + name0),
1417
                  (name1 + '/' + name1, name1, 'directory', './' + name1
1418
                                                            + '/' + name1),
1419
                 ]
1420
                ),
1421
                ((name1 + '/' + name1, './' + name1 + '/' + name1),
1422
                 [
1423
                 ]
1424
                ),
1425
            ]
1426
        result = []
1427
        # For ease in testing, if walkdirs_utf8 returns Unicode, assert that
1428
        # all abspaths are Unicode, and encode them back into utf8.
1429
        for dirdetail, dirblock in osutils._walkdirs_utf8('.'):
1430
            self.assertIsInstance(dirdetail[0], str)
1431
            if isinstance(dirdetail[1], unicode):
2324.2.4 by Dmitry Vasiliev
Fixed test_unicode__walkdirs_utf8 test
1432
                dirdetail = (dirdetail[0], dirdetail[1].encode('utf8'))
1433
                dirblock = [list(info) for info in dirblock]
2255.7.32 by John Arbash Meinel
Add tests that the walkdirs variants work on unicode paths.
1434
                for info in dirblock:
1435
                    self.assertIsInstance(info[4], unicode)
1436
                    info[4] = info[4].encode('utf8')
1437
            new_dirblock = []
1438
            for info in dirblock:
1439
                self.assertIsInstance(info[0], str)
1440
                self.assertIsInstance(info[1], str)
1441
                self.assertIsInstance(info[4], str)
1442
                # Remove the stat information
1443
                new_dirblock.append((info[0], info[1], info[2], info[4]))
1444
            result.append((dirdetail, new_dirblock))
1445
        self.assertEqual(expected_dirblocks, result)
1446
3696.3.1 by Robert Collins
Refactor bzrlib.osutils._walkdirs_utf8 to aid API migration in future.
1447
    def test__walkdirs_utf8_with_unicode_fs(self):
1448
        """UnicodeDirReader should be a safe fallback everywhere
2255.7.32 by John Arbash Meinel
Add tests that the walkdirs variants work on unicode paths.
1449
1450
        The abspath portion should be in unicode
1451
        """
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1452
        self.requireFeature(features.UnicodeFilenameFeature)
3696.3.1 by Robert Collins
Refactor bzrlib.osutils._walkdirs_utf8 to aid API migration in future.
1453
        # Use the unicode reader. TODO: split into driver-and-driven unit
1454
        # tests.
1455
        self._save_platform_info()
1456
        osutils._selected_dir_reader = osutils.UnicodeDirReader()
2255.7.32 by John Arbash Meinel
Add tests that the walkdirs variants work on unicode paths.
1457
        name0u = u'0file-\xb6'
1458
        name1u = u'1dir-\u062c\u0648'
1459
        name2u = u'2file-\u0633'
1460
        tree = [
1461
            name0u,
1462
            name1u + '/',
1463
            name1u + '/' + name0u,
1464
            name1u + '/' + name1u + '/',
1465
            name2u,
1466
            ]
4241.14.4 by Vincent Ladeuil
Clean up test_osutils.py.
1467
        self.build_tree(tree)
2255.7.32 by John Arbash Meinel
Add tests that the walkdirs variants work on unicode paths.
1468
        name0 = name0u.encode('utf8')
1469
        name1 = name1u.encode('utf8')
1470
        name2 = name2u.encode('utf8')
1471
1472
        # All of the abspaths should be in unicode, all of the relative paths
1473
        # should be in utf8
1474
        expected_dirblocks = [
1475
                (('', '.'),
1476
                 [(name0, name0, 'file', './' + name0u),
1477
                  (name1, name1, 'directory', './' + name1u),
1478
                  (name2, name2, 'file', './' + name2u),
1479
                 ]
1480
                ),
1481
                ((name1, './' + name1u),
1482
                 [(name1 + '/' + name0, name0, 'file', './' + name1u
1483
                                                        + '/' + name0u),
1484
                  (name1 + '/' + name1, name1, 'directory', './' + name1u
1485
                                                            + '/' + name1u),
1486
                 ]
1487
                ),
1488
                ((name1 + '/' + name1, './' + name1u + '/' + name1u),
1489
                 [
1490
                 ]
1491
                ),
1492
            ]
3696.3.1 by Robert Collins
Refactor bzrlib.osutils._walkdirs_utf8 to aid API migration in future.
1493
        result = list(osutils._walkdirs_utf8('.'))
2255.7.32 by John Arbash Meinel
Add tests that the walkdirs variants work on unicode paths.
1494
        self._filter_out_stat(result)
1495
        self.assertEqual(expected_dirblocks, result)
1496
3696.3.4 by John Arbash Meinel
Update the osutils test to find the objects in the right locations.
1497
    def test__walkdirs_utf8_win32readdir(self):
4913.2.26 by John Arbash Meinel
A bunch of osutils tests depended on features being available.
1498
        self.requireFeature(test__walkdirs_win32.win32_readdir_feature)
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1499
        self.requireFeature(features.UnicodeFilenameFeature)
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
1500
        from .._walkdirs_win32 import Win32ReadDir
3696.3.1 by Robert Collins
Refactor bzrlib.osutils._walkdirs_utf8 to aid API migration in future.
1501
        self._save_platform_info()
3696.3.4 by John Arbash Meinel
Update the osutils test to find the objects in the right locations.
1502
        osutils._selected_dir_reader = Win32ReadDir()
3504.4.1 by John Arbash Meinel
Write an alternative 'walkdirs' implementation that uses win32 apis.
1503
        name0u = u'0file-\xb6'
1504
        name1u = u'1dir-\u062c\u0648'
1505
        name2u = u'2file-\u0633'
1506
        tree = [
1507
            name0u,
1508
            name1u + '/',
1509
            name1u + '/' + name0u,
1510
            name1u + '/' + name1u + '/',
1511
            name2u,
1512
            ]
1513
        self.build_tree(tree)
1514
        name0 = name0u.encode('utf8')
1515
        name1 = name1u.encode('utf8')
1516
        name2 = name2u.encode('utf8')
1517
1518
        # All of the abspaths should be in unicode, all of the relative paths
1519
        # should be in utf8
1520
        expected_dirblocks = [
1521
                (('', '.'),
1522
                 [(name0, name0, 'file', './' + name0u),
1523
                  (name1, name1, 'directory', './' + name1u),
1524
                  (name2, name2, 'file', './' + name2u),
1525
                 ]
1526
                ),
1527
                ((name1, './' + name1u),
1528
                 [(name1 + '/' + name0, name0, 'file', './' + name1u
1529
                                                        + '/' + name0u),
1530
                  (name1 + '/' + name1, name1, 'directory', './' + name1u
1531
                                                            + '/' + name1u),
1532
                 ]
1533
                ),
1534
                ((name1 + '/' + name1, './' + name1u + '/' + name1u),
1535
                 [
1536
                 ]
1537
                ),
1538
            ]
3696.3.4 by John Arbash Meinel
Update the osutils test to find the objects in the right locations.
1539
        result = list(osutils._walkdirs_utf8(u'.'))
3504.4.1 by John Arbash Meinel
Write an alternative 'walkdirs' implementation that uses win32 apis.
1540
        self._filter_out_stat(result)
1541
        self.assertEqual(expected_dirblocks, result)
1542
3504.4.2 by John Arbash Meinel
Add a test case that shows the mtime is not being returned correctly.
1543
    def assertStatIsCorrect(self, path, win32stat):
1544
        os_stat = os.stat(path)
1545
        self.assertEqual(os_stat.st_size, win32stat.st_size)
3504.4.6 by John Arbash Meinel
Start exposing the times on the stat, this now seems to be a complete walkdirs implementation.
1546
        self.assertAlmostEqual(os_stat.st_mtime, win32stat.st_mtime, places=4)
1547
        self.assertAlmostEqual(os_stat.st_ctime, win32stat.st_ctime, places=4)
1548
        self.assertAlmostEqual(os_stat.st_atime, win32stat.st_atime, places=4)
3504.4.2 by John Arbash Meinel
Add a test case that shows the mtime is not being returned correctly.
1549
        self.assertEqual(os_stat.st_dev, win32stat.st_dev)
1550
        self.assertEqual(os_stat.st_ino, win32stat.st_ino)
1551
        self.assertEqual(os_stat.st_mode, win32stat.st_mode)
1552
1553
    def test__walkdirs_utf_win32_find_file_stat_file(self):
1554
        """make sure our Stat values are valid"""
4913.2.26 by John Arbash Meinel
A bunch of osutils tests depended on features being available.
1555
        self.requireFeature(test__walkdirs_win32.win32_readdir_feature)
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1556
        self.requireFeature(features.UnicodeFilenameFeature)
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
1557
        from .._walkdirs_win32 import Win32ReadDir
3504.4.2 by John Arbash Meinel
Add a test case that shows the mtime is not being returned correctly.
1558
        name0u = u'0file-\xb6'
1559
        name0 = name0u.encode('utf8')
1560
        self.build_tree([name0u])
1561
        # I hate to sleep() here, but I'm trying to make the ctime different
1562
        # from the mtime
1563
        time.sleep(2)
1564
        f = open(name0u, 'ab')
1565
        try:
1566
            f.write('just a small update')
1567
        finally:
1568
            f.close()
1569
3696.3.1 by Robert Collins
Refactor bzrlib.osutils._walkdirs_utf8 to aid API migration in future.
1570
        result = Win32ReadDir().read_dir('', u'.')
1571
        entry = result[0]
3504.4.2 by John Arbash Meinel
Add a test case that shows the mtime is not being returned correctly.
1572
        self.assertEqual((name0, name0, 'file'), entry[:3])
1573
        self.assertEqual(u'./' + name0u, entry[4])
1574
        self.assertStatIsCorrect(entry[4], entry[3])
3504.4.6 by John Arbash Meinel
Start exposing the times on the stat, this now seems to be a complete walkdirs implementation.
1575
        self.assertNotEqual(entry[3].st_mtime, entry[3].st_ctime)
3504.4.2 by John Arbash Meinel
Add a test case that shows the mtime is not being returned correctly.
1576
1577
    def test__walkdirs_utf_win32_find_file_stat_directory(self):
1578
        """make sure our Stat values are valid"""
4913.2.26 by John Arbash Meinel
A bunch of osutils tests depended on features being available.
1579
        self.requireFeature(test__walkdirs_win32.win32_readdir_feature)
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1580
        self.requireFeature(features.UnicodeFilenameFeature)
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
1581
        from .._walkdirs_win32 import Win32ReadDir
3504.4.2 by John Arbash Meinel
Add a test case that shows the mtime is not being returned correctly.
1582
        name0u = u'0dir-\u062c\u0648'
1583
        name0 = name0u.encode('utf8')
1584
        self.build_tree([name0u + '/'])
1585
3696.3.1 by Robert Collins
Refactor bzrlib.osutils._walkdirs_utf8 to aid API migration in future.
1586
        result = Win32ReadDir().read_dir('', u'.')
1587
        entry = result[0]
3504.4.2 by John Arbash Meinel
Add a test case that shows the mtime is not being returned correctly.
1588
        self.assertEqual((name0, name0, 'directory'), entry[:3])
1589
        self.assertEqual(u'./' + name0u, entry[4])
1590
        self.assertStatIsCorrect(entry[4], entry[3])
1591
1773.3.1 by Robert Collins
Add path_prefix_key and compare_paths_prefix_order utility functions.
1592
    def assertPathCompare(self, path_less, path_greater):
1593
        """check that path_less and path_greater compare correctly."""
1594
        self.assertEqual(0, osutils.compare_paths_prefix_order(
1595
            path_less, path_less))
1596
        self.assertEqual(0, osutils.compare_paths_prefix_order(
1597
            path_greater, path_greater))
1598
        self.assertEqual(-1, osutils.compare_paths_prefix_order(
1599
            path_less, path_greater))
1600
        self.assertEqual(1, osutils.compare_paths_prefix_order(
1601
            path_greater, path_less))
1602
1603
    def test_compare_paths_prefix_order(self):
1604
        # root before all else
1605
        self.assertPathCompare("/", "/a")
1606
        # alpha within a dir
1607
        self.assertPathCompare("/a", "/b")
1608
        self.assertPathCompare("/b", "/z")
1609
        # high dirs before lower.
1610
        self.assertPathCompare("/z", "/a/a")
1773.3.2 by Robert Collins
New corner case from John Meinel, showing up the need to check the directory lexographically outside of a single tree's root. Fixed.
1611
        # except if the deeper dir should be output first
1612
        self.assertPathCompare("/a/b/c", "/d/g")
1773.3.1 by Robert Collins
Add path_prefix_key and compare_paths_prefix_order utility functions.
1613
        # lexical betwen dirs of the same height
1614
        self.assertPathCompare("/a/z", "/z/z")
1615
        self.assertPathCompare("/a/c/z", "/a/d/e")
1616
1617
        # this should also be consistent for no leading / paths
1618
        # root before all else
1619
        self.assertPathCompare("", "a")
1620
        # alpha within a dir
1621
        self.assertPathCompare("a", "b")
1622
        self.assertPathCompare("b", "z")
1623
        # high dirs before lower.
1624
        self.assertPathCompare("z", "a/a")
1773.3.2 by Robert Collins
New corner case from John Meinel, showing up the need to check the directory lexographically outside of a single tree's root. Fixed.
1625
        # except if the deeper dir should be output first
1626
        self.assertPathCompare("a/b/c", "d/g")
1773.3.1 by Robert Collins
Add path_prefix_key and compare_paths_prefix_order utility functions.
1627
        # lexical betwen dirs of the same height
1628
        self.assertPathCompare("a/z", "z/z")
1629
        self.assertPathCompare("a/c/z", "a/d/e")
1630
1773.3.3 by Robert Collins
Add new tests John Meinel asked for.
1631
    def test_path_prefix_sorting(self):
1632
        """Doing a sort on path prefix should match our sample data."""
1633
        original_paths = [
1634
            'a',
1635
            'a/b',
1636
            'a/b/c',
1637
            'b',
1638
            'b/c',
1639
            'd',
1640
            'd/e',
1641
            'd/e/f',
1642
            'd/f',
1643
            'd/g',
1644
            'g',
1645
            ]
1646
1647
        dir_sorted_paths = [
1648
            'a',
1649
            'b',
1650
            'd',
1651
            'g',
1652
            'a/b',
1653
            'a/b/c',
1654
            'b/c',
1655
            'd/e',
1656
            'd/f',
1657
            'd/g',
1658
            'd/e/f',
1659
            ]
1660
1661
        self.assertEqual(
1662
            dir_sorted_paths,
1663
            sorted(original_paths, key=osutils.path_prefix_key))
1664
        # using the comparison routine shoudl work too:
1665
        self.assertEqual(
1666
            dir_sorted_paths,
1667
            sorted(original_paths, cmp=osutils.compare_paths_prefix_order))
1711.4.10 by John Arbash Meinel
Pull out sys.stdout.encoding handling into a separate function so it can be tested, and used elsewhere.
1668
1669
4241.14.3 by Vincent Ladeuil
Cleanup imports.
1670
class TestCopyTree(tests.TestCaseInTempDir):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1671
1907.3.1 by John Arbash Meinel
create a copy_tree wrapper around walkdirs()
1672
    def test_copy_basic_tree(self):
1673
        self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c'])
1674
        osutils.copy_tree('source', 'target')
2095.3.1 by Martin Pool
Tests shouldn't assume os.listdir returns sorted results
1675
        self.assertEqual(['a', 'b'], sorted(os.listdir('target')))
1907.3.1 by John Arbash Meinel
create a copy_tree wrapper around walkdirs()
1676
        self.assertEqual(['c'], os.listdir('target/b'))
1677
1678
    def test_copy_tree_target_exists(self):
1679
        self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c',
1680
                         'target/'])
1681
        osutils.copy_tree('source', 'target')
2095.3.1 by Martin Pool
Tests shouldn't assume os.listdir returns sorted results
1682
        self.assertEqual(['a', 'b'], sorted(os.listdir('target')))
1907.3.1 by John Arbash Meinel
create a copy_tree wrapper around walkdirs()
1683
        self.assertEqual(['c'], os.listdir('target/b'))
1684
1907.3.2 by John Arbash Meinel
Updated the copy_tree function to allow overriding functionality.
1685
    def test_copy_tree_symlinks(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1686
        self.requireFeature(features.SymlinkFeature)
1907.3.2 by John Arbash Meinel
Updated the copy_tree function to allow overriding functionality.
1687
        self.build_tree(['source/'])
1688
        os.symlink('a/generic/path', 'source/lnk')
1689
        osutils.copy_tree('source', 'target')
1690
        self.assertEqual(['lnk'], os.listdir('target'))
1691
        self.assertEqual('a/generic/path', os.readlink('target/lnk'))
1692
1693
    def test_copy_tree_handlers(self):
1694
        processed_files = []
1695
        processed_links = []
1696
        def file_handler(from_path, to_path):
1697
            processed_files.append(('f', from_path, to_path))
1698
        def dir_handler(from_path, to_path):
1699
            processed_files.append(('d', from_path, to_path))
1700
        def link_handler(from_path, to_path):
1701
            processed_links.append((from_path, to_path))
1702
        handlers = {'file':file_handler,
1703
                    'directory':dir_handler,
1704
                    'symlink':link_handler,
1705
                   }
1706
1707
        self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c'])
1708
        if osutils.has_symlinks():
1709
            os.symlink('a/generic/path', 'source/lnk')
1710
        osutils.copy_tree('source', 'target', handlers=handlers)
1711
1712
        self.assertEqual([('d', 'source', 'target'),
1713
                          ('f', 'source/a', 'target/a'),
1714
                          ('d', 'source/b', 'target/b'),
1715
                          ('f', 'source/b/c', 'target/b/c'),
1716
                         ], processed_files)
5784.1.3 by Martin Pool
Switch away from using failUnlessExists and failIfExists
1717
        self.assertPathDoesNotExist('target')
1907.3.2 by John Arbash Meinel
Updated the copy_tree function to allow overriding functionality.
1718
        if osutils.has_symlinks():
1719
            self.assertEqual([('source/lnk', 'target/lnk')], processed_links)
1720
1907.3.1 by John Arbash Meinel
create a copy_tree wrapper around walkdirs()
1721
4241.14.3 by Vincent Ladeuil
Cleanup imports.
1722
class TestSetUnsetEnv(tests.TestCase):
1963.1.5 by John Arbash Meinel
Create an osutils helper function for modifying the environment
1723
    """Test updating the environment"""
1724
1725
    def setUp(self):
1726
        super(TestSetUnsetEnv, self).setUp()
1727
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
1728
        self.assertEqual(None, os.environ.get('BRZ_TEST_ENV_VAR'),
1963.1.5 by John Arbash Meinel
Create an osutils helper function for modifying the environment
1729
                         'Environment was not cleaned up properly.'
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
1730
                         ' Variable BRZ_TEST_ENV_VAR should not exist.')
1963.1.5 by John Arbash Meinel
Create an osutils helper function for modifying the environment
1731
        def cleanup():
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
1732
            if 'BRZ_TEST_ENV_VAR' in os.environ:
1733
                del os.environ['BRZ_TEST_ENV_VAR']
1963.1.5 by John Arbash Meinel
Create an osutils helper function for modifying the environment
1734
        self.addCleanup(cleanup)
1735
1736
    def test_set(self):
1737
        """Test that we can set an env variable"""
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
1738
        old = osutils.set_or_unset_env('BRZ_TEST_ENV_VAR', 'foo')
1963.1.5 by John Arbash Meinel
Create an osutils helper function for modifying the environment
1739
        self.assertEqual(None, old)
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
1740
        self.assertEqual('foo', os.environ.get('BRZ_TEST_ENV_VAR'))
1963.1.5 by John Arbash Meinel
Create an osutils helper function for modifying the environment
1741
1742
    def test_double_set(self):
1743
        """Test that we get the old value out"""
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
1744
        osutils.set_or_unset_env('BRZ_TEST_ENV_VAR', 'foo')
1745
        old = osutils.set_or_unset_env('BRZ_TEST_ENV_VAR', 'bar')
1963.1.5 by John Arbash Meinel
Create an osutils helper function for modifying the environment
1746
        self.assertEqual('foo', old)
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
1747
        self.assertEqual('bar', os.environ.get('BRZ_TEST_ENV_VAR'))
1963.1.5 by John Arbash Meinel
Create an osutils helper function for modifying the environment
1748
1749
    def test_unicode(self):
1750
        """Environment can only contain plain strings
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1751
1963.1.5 by John Arbash Meinel
Create an osutils helper function for modifying the environment
1752
        So Unicode strings must be encoded.
1753
        """
4241.14.3 by Vincent Ladeuil
Cleanup imports.
1754
        uni_val, env_val = tests.probe_unicode_in_user_encoding()
2785.1.5 by Alexander Belchenko
support for non-ascii BZR_HOME in show_version()
1755
        if uni_val is None:
4241.14.3 by Vincent Ladeuil
Cleanup imports.
1756
            raise tests.TestSkipped(
1757
                'Cannot find a unicode character that works in encoding %s'
1758
                % (osutils.get_user_encoding(),))
1963.1.5 by John Arbash Meinel
Create an osutils helper function for modifying the environment
1759
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
1760
        old = osutils.set_or_unset_env('BRZ_TEST_ENV_VAR', uni_val)
1761
        self.assertEqual(env_val, os.environ.get('BRZ_TEST_ENV_VAR'))
1963.1.5 by John Arbash Meinel
Create an osutils helper function for modifying the environment
1762
1763
    def test_unset(self):
1764
        """Test that passing None will remove the env var"""
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
1765
        osutils.set_or_unset_env('BRZ_TEST_ENV_VAR', 'foo')
1766
        old = osutils.set_or_unset_env('BRZ_TEST_ENV_VAR', None)
1963.1.5 by John Arbash Meinel
Create an osutils helper function for modifying the environment
1767
        self.assertEqual('foo', old)
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
1768
        self.assertEqual(None, os.environ.get('BRZ_TEST_ENV_VAR'))
1769
        self.assertFalse('BRZ_TEST_ENV_VAR' in os.environ)
1963.1.5 by John Arbash Meinel
Create an osutils helper function for modifying the environment
1770
2215.6.2 by James Henstridge
add some simple tests for local_time_offset()
1771
4241.14.3 by Vincent Ladeuil
Cleanup imports.
1772
class TestSizeShaFile(tests.TestCaseInTempDir):
3368.2.49 by Ian Clatworthy
added osutils.size_sha_file() with tests
1773
1774
    def test_sha_empty(self):
1775
        self.build_tree_contents([('foo', '')])
1776
        expected_sha = osutils.sha_string('')
1777
        f = open('foo')
1778
        self.addCleanup(f.close)
1779
        size, sha = osutils.size_sha_file(f)
1780
        self.assertEqual(0, size)
1781
        self.assertEqual(expected_sha, sha)
1782
1783
    def test_sha_mixed_endings(self):
1784
        text = 'test\r\nwith\nall\rpossible line endings\r\n'
1785
        self.build_tree_contents([('foo', text)])
1786
        expected_sha = osutils.sha_string(text)
4789.25.1 by John Arbash Meinel
When computing the sha1sum for a file, make sure it is opened in binary mode.
1787
        f = open('foo', 'rb')
3368.2.49 by Ian Clatworthy
added osutils.size_sha_file() with tests
1788
        self.addCleanup(f.close)
1789
        size, sha = osutils.size_sha_file(f)
1790
        self.assertEqual(38, size)
1791
        self.assertEqual(expected_sha, sha)
1792
1793
4241.14.3 by Vincent Ladeuil
Cleanup imports.
1794
class TestShaFileByName(tests.TestCaseInTempDir):
2922.1.2 by John Arbash Meinel
Add tests for sha_file_by_name.
1795
1796
    def test_sha_empty(self):
1797
        self.build_tree_contents([('foo', '')])
1798
        expected_sha = osutils.sha_string('')
1799
        self.assertEqual(expected_sha, osutils.sha_file_by_name('foo'))
1800
1801
    def test_sha_mixed_endings(self):
1802
        text = 'test\r\nwith\nall\rpossible line endings\r\n'
1803
        self.build_tree_contents([('foo', text)])
1804
        expected_sha = osutils.sha_string(text)
1805
        self.assertEqual(expected_sha, osutils.sha_file_by_name('foo'))
3089.3.9 by Ian Clatworthy
add test for resource loading
1806
1807
4241.14.3 by Vincent Ladeuil
Cleanup imports.
1808
class TestResourceLoading(tests.TestCaseInTempDir):
3089.3.9 by Ian Clatworthy
add test for resource loading
1809
1810
    def test_resource_string(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
1811
        # test resource in breezy
1812
        text = osutils.resource_string('breezy', 'debug.py')
3959.1.4 by Martin Pool
test_resource_string shouldn't depend on the precise source file contents
1813
        self.assertContainsRe(text, "debug_flags = set()")
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
1814
        # test resource under breezy
1815
        text = osutils.resource_string('breezy.ui', 'text.py')
3089.3.9 by Ian Clatworthy
add test for resource loading
1816
        self.assertContainsRe(text, "class TextUIFactory")
1817
        # test unsupported package
1818
        self.assertRaises(errors.BzrError, osutils.resource_string, 'zzzz',
1819
            'yyy.xx')
1820
        # test unknown resource
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
1821
        self.assertRaises(IOError, osutils.resource_string, 'breezy', 'yyy.xx')
4183.6.4 by Martin Pool
Separate out re_compile_checked
1822
1823
4241.14.6 by Vincent Ladeuil
Start DirReader parametrized tests.
1824
class TestDirReader(tests.TestCaseInTempDir):
1825
5559.2.2 by Martin Pool
Change to using standard load_tests_apply_scenarios.
1826
    scenarios = dir_reader_scenarios()
1827
4241.14.6 by Vincent Ladeuil
Start DirReader parametrized tests.
1828
    # Set by load_tests
1829
    _dir_reader_class = None
1830
    _native_to_unicode = None
1831
1832
    def setUp(self):
6552.1.4 by Vincent Ladeuil
Remaining tests matching setup(self) that can be rewritten with super().
1833
        super(TestDirReader, self).setUp()
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
1834
        self.overrideAttr(osutils,
1835
                          '_selected_dir_reader', self._dir_reader_class())
4241.14.6 by Vincent Ladeuil
Start DirReader parametrized tests.
1836
1837
    def _get_ascii_tree(self):
1838
        tree = [
1839
            '0file',
1840
            '1dir/',
1841
            '1dir/0file',
1842
            '1dir/1dir/',
1843
            '2file'
1844
            ]
1845
        expected_dirblocks = [
1846
                (('', '.'),
1847
                 [('0file', '0file', 'file'),
1848
                  ('1dir', '1dir', 'directory'),
1849
                  ('2file', '2file', 'file'),
1850
                 ]
1851
                ),
1852
                (('1dir', './1dir'),
1853
                 [('1dir/0file', '0file', 'file'),
1854
                  ('1dir/1dir', '1dir', 'directory'),
1855
                 ]
1856
                ),
1857
                (('1dir/1dir', './1dir/1dir'),
1858
                 [
1859
                 ]
1860
                ),
1861
            ]
1862
        return tree, expected_dirblocks
1863
1864
    def test_walk_cur_dir(self):
1865
        tree, expected_dirblocks = self._get_ascii_tree()
1866
        self.build_tree(tree)
1867
        result = list(osutils._walkdirs_utf8('.'))
1868
        # Filter out stat and abspath
1869
        self.assertEqual(expected_dirblocks,
1870
                         [(dirinfo, [line[0:3] for line in block])
1871
                          for dirinfo, block in result])
1872
1873
    def test_walk_sub_dir(self):
1874
        tree, expected_dirblocks = self._get_ascii_tree()
1875
        self.build_tree(tree)
1876
        # you can search a subdir only, with a supplied prefix.
1877
        result = list(osutils._walkdirs_utf8('./1dir', '1dir'))
1878
        # Filter out stat and abspath
1879
        self.assertEqual(expected_dirblocks[1:],
1880
                         [(dirinfo, [line[0:3] for line in block])
1881
                          for dirinfo, block in result])
1882
1883
    def _get_unicode_tree(self):
1884
        name0u = u'0file-\xb6'
1885
        name1u = u'1dir-\u062c\u0648'
1886
        name2u = u'2file-\u0633'
1887
        tree = [
1888
            name0u,
1889
            name1u + '/',
1890
            name1u + '/' + name0u,
1891
            name1u + '/' + name1u + '/',
1892
            name2u,
1893
            ]
1894
        name0 = name0u.encode('UTF-8')
1895
        name1 = name1u.encode('UTF-8')
1896
        name2 = name2u.encode('UTF-8')
1897
        expected_dirblocks = [
1898
                (('', '.'),
1899
                 [(name0, name0, 'file', './' + name0u),
1900
                  (name1, name1, 'directory', './' + name1u),
1901
                  (name2, name2, 'file', './' + name2u),
1902
                 ]
1903
                ),
1904
                ((name1, './' + name1u),
1905
                 [(name1 + '/' + name0, name0, 'file', './' + name1u
1906
                                                        + '/' + name0u),
1907
                  (name1 + '/' + name1, name1, 'directory', './' + name1u
1908
                                                            + '/' + name1u),
1909
                 ]
1910
                ),
1911
                ((name1 + '/' + name1, './' + name1u + '/' + name1u),
1912
                 [
1913
                 ]
1914
                ),
1915
            ]
1916
        return tree, expected_dirblocks
1917
4241.14.7 by Vincent Ladeuil
Add a test for symlinks name handling.
1918
    def _filter_out(self, raw_dirblocks):
1919
        """Filter out a walkdirs_utf8 result.
1920
1921
        stat field is removed, all native paths are converted to unicode
1922
        """
1923
        filtered_dirblocks = []
1924
        for dirinfo, block in raw_dirblocks:
4241.14.6 by Vincent Ladeuil
Start DirReader parametrized tests.
1925
            dirinfo = (dirinfo[0], self._native_to_unicode(dirinfo[1]))
1926
            details = []
1927
            for line in block:
4789.25.5 by John Arbash Meinel
Remove a pdb.set_trace() call.
1928
                details.append(line[0:3] + (self._native_to_unicode(line[4]), ))
4241.14.7 by Vincent Ladeuil
Add a test for symlinks name handling.
1929
            filtered_dirblocks.append((dirinfo, details))
1930
        return filtered_dirblocks
1931
1932
    def test_walk_unicode_tree(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1933
        self.requireFeature(features.UnicodeFilenameFeature)
4241.14.7 by Vincent Ladeuil
Add a test for symlinks name handling.
1934
        tree, expected_dirblocks = self._get_unicode_tree()
1935
        self.build_tree(tree)
1936
        result = list(osutils._walkdirs_utf8('.'))
1937
        self.assertEqual(expected_dirblocks, self._filter_out(result))
1938
1939
    def test_symlink(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1940
        self.requireFeature(features.SymlinkFeature)
1941
        self.requireFeature(features.UnicodeFilenameFeature)
4241.14.14 by Vincent Ladeuil
Test and implements osutils.readlink().
1942
        target = u'target\N{Euro Sign}'
1943
        link_name = u'l\N{Euro Sign}nk'
4241.14.7 by Vincent Ladeuil
Add a test for symlinks name handling.
1944
        os.symlink(target, link_name)
1945
        target_utf8 = target.encode('UTF-8')
1946
        link_name_utf8 = link_name.encode('UTF-8')
1947
        expected_dirblocks = [
1948
                (('', '.'),
1949
                 [(link_name_utf8, link_name_utf8,
1950
                   'symlink', './' + link_name),],
1951
                 )]
1952
        result = list(osutils._walkdirs_utf8('.'))
1953
        self.assertEqual(expected_dirblocks, self._filter_out(result))
4241.14.14 by Vincent Ladeuil
Test and implements osutils.readlink().
1954
1955
1956
class TestReadLink(tests.TestCaseInTempDir):
1957
    """Exposes os.readlink() problems and the osutils solution.
1958
1959
    The only guarantee offered by os.readlink(), starting with 2.6, is that a
1960
    unicode string will be returned if a unicode string is passed.
1961
4241.14.25 by Vincent Ladeuil
Fix PQM failures.
1962
    But prior python versions failed to properly encode the passed unicode
4241.14.14 by Vincent Ladeuil
Test and implements osutils.readlink().
1963
    string.
1964
    """
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
1965
    _test_needs_features = [features.SymlinkFeature, features.UnicodeFilenameFeature]
4241.14.14 by Vincent Ladeuil
Test and implements osutils.readlink().
1966
1967
    def setUp(self):
1968
        super(tests.TestCaseInTempDir, self).setUp()
1969
        self.link = u'l\N{Euro Sign}ink'
1970
        self.target = u'targe\N{Euro Sign}t'
1971
        os.symlink(self.target, self.link)
1972
1973
    def test_os_readlink_link_encoding(self):
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1974
        self.assertEqual(self.target,  os.readlink(self.link))
4241.14.14 by Vincent Ladeuil
Test and implements osutils.readlink().
1975
1976
    def test_os_readlink_link_decoding(self):
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1977
        self.assertEqual(self.target.encode(osutils._fs_enc),
4241.14.14 by Vincent Ladeuil
Test and implements osutils.readlink().
1978
                          os.readlink(self.link.encode(osutils._fs_enc)))
4398.4.3 by Vincent Ladeuil
Detect # cores on win32 and Solaris too.
1979
1980
1981
class TestConcurrency(tests.TestCase):
1982
4766.3.4 by Matt Nordhoff
Change the environment variable to a global option.
1983
    def setUp(self):
1984
        super(TestConcurrency, self).setUp()
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
1985
        self.overrideAttr(osutils, '_cached_local_concurrency')
4766.3.4 by Matt Nordhoff
Change the environment variable to a global option.
1986
4398.4.3 by Vincent Ladeuil
Detect # cores on win32 and Solaris too.
1987
    def test_local_concurrency(self):
1988
        concurrency = osutils.local_concurrency()
1989
        self.assertIsInstance(concurrency, int)
4574.3.3 by Martin Pool
Add test for failure to load extensions
1990
4766.3.7 by Vincent Ladeuil
Mix BZR_CONCURRENCY and --concurrency so both are available.
1991
    def test_local_concurrency_environment_variable(self):
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
1992
        self.overrideEnv('BRZ_CONCURRENCY', '2')
4766.3.7 by Vincent Ladeuil
Mix BZR_CONCURRENCY and --concurrency so both are available.
1993
        self.assertEqual(2, osutils.local_concurrency(use_cache=False))
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
1994
        self.overrideEnv('BRZ_CONCURRENCY', '3')
4766.3.7 by Vincent Ladeuil
Mix BZR_CONCURRENCY and --concurrency so both are available.
1995
        self.assertEqual(3, osutils.local_concurrency(use_cache=False))
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
1996
        self.overrideEnv('BRZ_CONCURRENCY', 'foo')
4766.3.7 by Vincent Ladeuil
Mix BZR_CONCURRENCY and --concurrency so both are available.
1997
        self.assertEqual(1, osutils.local_concurrency(use_cache=False))
1998
1999
    def test_option_concurrency(self):
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
2000
        self.overrideEnv('BRZ_CONCURRENCY', '1')
4766.3.7 by Vincent Ladeuil
Mix BZR_CONCURRENCY and --concurrency so both are available.
2001
        self.run_bzr('rocks --concurrency 42')
5570.3.9 by Vincent Ladeuil
More use cases for overrideEnv, _cleanEnvironment *may* contain too much variables now.
2002
        # Command line overrides environment variable
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
2003
        self.assertEqual('42', os.environ['BRZ_CONCURRENCY'])
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
2004
        self.assertEqual(42, osutils.local_concurrency(use_cache=False))
4766.3.1 by Matt Nordhoff
Add a BZR_CONCURRENCY environment variable, so users can control osutils.local_concurrency()
2005
4574.3.3 by Martin Pool
Add test for failure to load extensions
2006
2007
class TestFailedToLoadExtension(tests.TestCase):
2008
2009
    def _try_loading(self):
2010
        try:
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
2011
            import breezy._fictional_extension_py
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
2012
        except ImportError as e:
4574.3.8 by Martin Pool
Only mutter extension load errors when they occur, and record for later
2013
            osutils.failed_to_load_extension(e)
4574.3.3 by Martin Pool
Add test for failure to load extensions
2014
            return True
2015
4574.3.8 by Martin Pool
Only mutter extension load errors when they occur, and record for later
2016
    def setUp(self):
2017
        super(TestFailedToLoadExtension, self).setUp()
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
2018
        self.overrideAttr(osutils, '_extension_load_failures', [])
4574.3.8 by Martin Pool
Only mutter extension load errors when they occur, and record for later
2019
4574.3.3 by Martin Pool
Add test for failure to load extensions
2020
    def test_failure_to_load(self):
4574.3.8 by Martin Pool
Only mutter extension load errors when they occur, and record for later
2021
        self._try_loading()
2022
        self.assertLength(1, osutils._extension_load_failures)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
2023
        self.assertEqual(osutils._extension_load_failures[0],
4574.3.8 by Martin Pool
Only mutter extension load errors when they occur, and record for later
2024
            "No module named _fictional_extension_py")
2025
4695.4.1 by Martin Pool
Give a shorter/cleaner message for missing extensions
2026
    def test_report_extension_load_failures_no_warning(self):
4574.3.8 by Martin Pool
Only mutter extension load errors when they occur, and record for later
2027
        self.assertTrue(self._try_loading())
2028
        warnings, result = self.callCatchWarnings(osutils.report_extension_load_failures)
4695.4.1 by Martin Pool
Give a shorter/cleaner message for missing extensions
2029
        # it used to give a Python warning; it no longer does
2030
        self.assertLength(0, warnings)
2031
2032
    def test_report_extension_load_failures_message(self):
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
2033
        log = BytesIO()
4695.4.1 by Martin Pool
Give a shorter/cleaner message for missing extensions
2034
        trace.push_log_file(log)
2035
        self.assertTrue(self._try_loading())
2036
        osutils.report_extension_load_failures()
2037
        self.assertContainsRe(
2038
            log.getvalue(),
6622.1.4 by Jelmer Vernooij
Fix some more tests.
2039
            r"brz: warning: some compiled extensions could not be loaded; "
4695.4.1 by Martin Pool
Give a shorter/cleaner message for missing extensions
2040
            "see <https://answers\.launchpad\.net/bzr/\+faq/703>\n"
2041
            )
4747.3.4 by Vincent Ladeuil
Add tests, introduce explicit default values, always respect COLUMNS.
2042
2043
2044
class TestTerminalWidth(tests.TestCase):
2045
4797.54.2 by Andrew Bennetts
Try to preserve the 'use COLUMNS until SIGWINCH' behaviour without using SIGWINCH, to keep the behaviour in 2.1 as stable as possible.
2046
    def setUp(self):
6552.1.3 by Vincent Ladeuil
Use super() instead of calling <base>.setup(self), as the original fix illustrated a too-easy-to-fall-into trap.
2047
        super(TestTerminalWidth, self).setUp()
4797.54.2 by Andrew Bennetts
Try to preserve the 'use COLUMNS until SIGWINCH' behaviour without using SIGWINCH, to keep the behaviour in 2.1 as stable as possible.
2048
        self._orig_terminal_size_state = osutils._terminal_size_state
2049
        self._orig_first_terminal_size = osutils._first_terminal_size
2050
        self.addCleanup(self.restore_osutils_globals)
2051
        osutils._terminal_size_state = 'no_data'
2052
        osutils._first_terminal_size = None
2053
2054
    def restore_osutils_globals(self):
2055
        osutils._terminal_size_state = self._orig_terminal_size_state
2056
        osutils._first_terminal_size = self._orig_first_terminal_size
5279.2.9 by Eric Moritz
Deleted trailing whitespace
2057
4747.4.5 by Vincent Ladeuil
More robusts tests for osutils.terminal_width().
2058
    def replace_stdout(self, new):
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
2059
        self.overrideAttr(sys, 'stdout', new)
4747.4.5 by Vincent Ladeuil
More robusts tests for osutils.terminal_width().
2060
2061
    def replace__terminal_size(self, new):
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
2062
        self.overrideAttr(osutils, '_terminal_size', new)
4747.4.5 by Vincent Ladeuil
More robusts tests for osutils.terminal_width().
2063
4747.4.7 by Vincent Ladeuil
Fix broken test (fail on windows).
2064
    def set_fake_tty(self):
2065
2066
        class I_am_a_tty(object):
2067
            def isatty(self):
2068
                return True
2069
2070
        self.replace_stdout(I_am_a_tty())
2071
4747.3.4 by Vincent Ladeuil
Add tests, introduce explicit default values, always respect COLUMNS.
2072
    def test_default_values(self):
4747.4.5 by Vincent Ladeuil
More robusts tests for osutils.terminal_width().
2073
        self.assertEqual(80, osutils.default_terminal_width)
4747.3.4 by Vincent Ladeuil
Add tests, introduce explicit default values, always respect COLUMNS.
2074
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
2075
    def test_defaults_to_BRZ_COLUMNS(self):
2076
        # BRZ_COLUMNS is set by the test framework
2077
        self.assertNotEqual('12', os.environ['BRZ_COLUMNS'])
2078
        self.overrideEnv('BRZ_COLUMNS', '12')
4747.4.5 by Vincent Ladeuil
More robusts tests for osutils.terminal_width().
2079
        self.assertEqual(12, osutils.terminal_width())
4747.3.4 by Vincent Ladeuil
Add tests, introduce explicit default values, always respect COLUMNS.
2080
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
2081
    def test_BRZ_COLUMNS_0_no_limit(self):
2082
        self.overrideEnv('BRZ_COLUMNS', '0')
5582.7.1 by Neil Martinsen-Burrell
allow BZR_COLUMNS to be 0
2083
        self.assertEqual(None, osutils.terminal_width())
2084
4747.4.3 by Vincent Ladeuil
Re-fix the priority order since there is a known valid case.
2085
    def test_falls_back_to_COLUMNS(self):
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
2086
        self.overrideEnv('BRZ_COLUMNS', None)
4747.4.5 by Vincent Ladeuil
More robusts tests for osutils.terminal_width().
2087
        self.assertNotEqual('42', os.environ['COLUMNS'])
4747.4.7 by Vincent Ladeuil
Fix broken test (fail on windows).
2088
        self.set_fake_tty()
5570.3.9 by Vincent Ladeuil
More use cases for overrideEnv, _cleanEnvironment *may* contain too much variables now.
2089
        self.overrideEnv('COLUMNS', '42')
4747.4.5 by Vincent Ladeuil
More robusts tests for osutils.terminal_width().
2090
        self.assertEqual(42, osutils.terminal_width())
4747.4.3 by Vincent Ladeuil
Re-fix the priority order since there is a known valid case.
2091
4747.3.4 by Vincent Ladeuil
Add tests, introduce explicit default values, always respect COLUMNS.
2092
    def test_tty_default_without_columns(self):
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
2093
        self.overrideEnv('BRZ_COLUMNS', None)
5570.3.9 by Vincent Ladeuil
More use cases for overrideEnv, _cleanEnvironment *may* contain too much variables now.
2094
        self.overrideEnv('COLUMNS', None)
4747.3.5 by Vincent Ladeuil
More precise test.
2095
4747.4.5 by Vincent Ladeuil
More robusts tests for osutils.terminal_width().
2096
        def terminal_size(w, h):
2097
            return 42, 42
2098
4747.4.7 by Vincent Ladeuil
Fix broken test (fail on windows).
2099
        self.set_fake_tty()
4747.4.5 by Vincent Ladeuil
More robusts tests for osutils.terminal_width().
2100
        # We need to override the osutils definition as it depends on the
2101
        # running environment that we can't control (PQM running without a
2102
        # controlling terminal is one example).
2103
        self.replace__terminal_size(terminal_size)
2104
        self.assertEqual(42, osutils.terminal_width())
4747.3.4 by Vincent Ladeuil
Add tests, introduce explicit default values, always respect COLUMNS.
2105
2106
    def test_non_tty_default_without_columns(self):
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
2107
        self.overrideEnv('BRZ_COLUMNS', None)
5570.3.9 by Vincent Ladeuil
More use cases for overrideEnv, _cleanEnvironment *may* contain too much variables now.
2108
        self.overrideEnv('COLUMNS', None)
4747.4.5 by Vincent Ladeuil
More robusts tests for osutils.terminal_width().
2109
        self.replace_stdout(None)
2110
        self.assertEqual(None, osutils.terminal_width())
4747.3.4 by Vincent Ladeuil
Add tests, introduce explicit default values, always respect COLUMNS.
2111
4873.2.2 by John Arbash Meinel
Change the TIOCGWINSZ test to use a _ModuleFeature. (fixes bug #492561)
2112
    def test_no_TIOCGWINSZ(self):
4913.2.20 by John Arbash Meinel
Change all of the compiled_foo to compiled_foo_feature
2113
        self.requireFeature(term_ios_feature)
2114
        termios = term_ios_feature.module
4747.3.4 by Vincent Ladeuil
Add tests, introduce explicit default values, always respect COLUMNS.
2115
        # bug 63539 is about a termios without TIOCGWINSZ attribute
2116
        try:
2117
            orig = termios.TIOCGWINSZ
2118
        except AttributeError:
4873.2.2 by John Arbash Meinel
Change the TIOCGWINSZ test to use a _ModuleFeature. (fixes bug #492561)
2119
            # We won't remove TIOCGWINSZ, because it doesn't exist anyway :)
2120
            pass
2121
        else:
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
2122
            self.overrideAttr(termios, 'TIOCGWINSZ')
4873.2.2 by John Arbash Meinel
Change the TIOCGWINSZ test to use a _ModuleFeature. (fixes bug #492561)
2123
            del termios.TIOCGWINSZ
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
2124
        self.overrideEnv('BRZ_COLUMNS', None)
5570.3.9 by Vincent Ladeuil
More use cases for overrideEnv, _cleanEnvironment *may* contain too much variables now.
2125
        self.overrideEnv('COLUMNS', None)
4747.4.5 by Vincent Ladeuil
More robusts tests for osutils.terminal_width().
2126
        # Whatever the result is, if we don't raise an exception, it's ok.
2127
        osutils.terminal_width()
5051.4.3 by Parth Malwankar
added tests for osutils.{parent_dir, mkdir, open}
2128
5609.47.2 by Alexander Belchenko
getuser_unicode: catch "ImportError: No module named pwd" on Windows when bzr is running as a service.
2129
5051.4.3 by Parth Malwankar
added tests for osutils.{parent_dir, mkdir, open}
2130
class TestCreationOps(tests.TestCaseInTempDir):
5051.4.11 by Parth Malwankar
closed Martins review comments.
2131
    _test_needs_features = [features.chown_feature]
5051.4.3 by Parth Malwankar
added tests for osutils.{parent_dir, mkdir, open}
2132
2133
    def setUp(self):
6552.1.4 by Vincent Ladeuil
Remaining tests matching setup(self) that can be rewritten with super().
2134
        super(TestCreationOps, self).setUp()
5051.4.9 by Parth Malwankar
removed parent_dir.
2135
        self.overrideAttr(os, 'chown', self._dummy_chown)
5051.4.3 by Parth Malwankar
added tests for osutils.{parent_dir, mkdir, open}
2136
2137
        # params set by call to _dummy_chown
2138
        self.path = self.uid = self.gid = None
2139
2140
    def _dummy_chown(self, path, uid, gid):
2141
        self.path, self.uid, self.gid = path, uid, gid
2142
5116.2.6 by Parth Malwankar
renamed copy_ownership to copy_ownership_from_path.
2143
    def test_copy_ownership_from_path(self):
5116.2.11 by Vincent Ladeuil
Fix typos.
2144
        """copy_ownership_from_path test with specified src."""
5116.2.3 by Parth Malwankar
updated log file creation to avoid race based on implementation by Martin [gz]
2145
        ownsrc = '/'
2146
        f = open('test_file', 'wt')
5116.2.11 by Vincent Ladeuil
Fix typos.
2147
        osutils.copy_ownership_from_path('test_file', ownsrc)
5116.2.3 by Parth Malwankar
updated log file creation to avoid race based on implementation by Martin [gz]
2148
2149
        s = os.stat(ownsrc)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
2150
        self.assertEqual(self.path, 'test_file')
2151
        self.assertEqual(self.uid, s.st_uid)
2152
        self.assertEqual(self.gid, s.st_gid)
5116.2.3 by Parth Malwankar
updated log file creation to avoid race based on implementation by Martin [gz]
2153
2154
    def test_copy_ownership_nonesrc(self):
5116.2.11 by Vincent Ladeuil
Fix typos.
2155
        """copy_ownership_from_path test with src=None."""
5116.2.3 by Parth Malwankar
updated log file creation to avoid race based on implementation by Martin [gz]
2156
        f = open('test_file', 'wt')
2157
        # should use parent dir for permissions
5116.2.11 by Vincent Ladeuil
Fix typos.
2158
        osutils.copy_ownership_from_path('test_file')
5116.2.3 by Parth Malwankar
updated log file creation to avoid race based on implementation by Martin [gz]
2159
2160
        s = os.stat('..')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
2161
        self.assertEqual(self.path, 'test_file')
2162
        self.assertEqual(self.uid, s.st_uid)
2163
        self.assertEqual(self.gid, s.st_gid)
5187.2.8 by Parth Malwankar
added tests for getuser_unicode
2164
5609.47.2 by Alexander Belchenko
getuser_unicode: catch "ImportError: No module named pwd" on Windows when bzr is running as a service.
2165
6437.26.2 by Martin Packman
Add some similar tests for path_from_environ as well
2166
class TestPathFromEnviron(tests.TestCase):
2167
2168
    def test_is_unicode(self):
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
2169
        self.overrideEnv('BRZ_TEST_PATH', './anywhere at all/')
2170
        path = osutils.path_from_environ('BRZ_TEST_PATH')
6437.26.2 by Martin Packman
Add some similar tests for path_from_environ as well
2171
        self.assertIsInstance(path, unicode)
2172
        self.assertEqual(u'./anywhere at all/', path)
2173
2174
    def test_posix_path_env_ascii(self):
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
2175
        self.overrideEnv('BRZ_TEST_PATH', '/tmp')
2176
        home = osutils._posix_path_from_environ('BRZ_TEST_PATH')
6437.26.2 by Martin Packman
Add some similar tests for path_from_environ as well
2177
        self.assertIsInstance(home, unicode)
2178
        self.assertEqual(u'/tmp', home)
2179
2180
    def test_posix_path_env_unicode(self):
2181
        self.requireFeature(features.ByteStringNamedFilesystem)
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
2182
        self.overrideEnv('BRZ_TEST_PATH', '/home/\xa7test')
6437.26.2 by Martin Packman
Add some similar tests for path_from_environ as well
2183
        self.overrideAttr(osutils, "_fs_enc", "iso8859-1")
2184
        self.assertEqual(u'/home/\xa7test',
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
2185
            osutils._posix_path_from_environ('BRZ_TEST_PATH'))
6437.26.2 by Martin Packman
Add some similar tests for path_from_environ as well
2186
        osutils._fs_enc = "iso8859-5"
2187
        self.assertEqual(u'/home/\u0407test',
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
2188
            osutils._posix_path_from_environ('BRZ_TEST_PATH'))
6437.26.2 by Martin Packman
Add some similar tests for path_from_environ as well
2189
        osutils._fs_enc = "utf-8"
2190
        self.assertRaises(errors.BadFilenameEncoding,
6622.1.28 by Jelmer Vernooij
More renames; commands in output, environment variables.
2191
            osutils._posix_path_from_environ, 'BRZ_TEST_PATH')
6437.26.2 by Martin Packman
Add some similar tests for path_from_environ as well
2192
2193
6437.26.1 by Martin Packman
Add and test osutils._get_home_dir for unicode access to home location across platforms
2194
class TestGetHomeDir(tests.TestCase):
2195
2196
    def test_is_unicode(self):
2197
        home = osutils._get_home_dir()
2198
        self.assertIsInstance(home, unicode)
2199
2200
    def test_posix_homeless(self):
2201
        self.overrideEnv('HOME', None)
2202
        home = osutils._get_home_dir()
2203
        self.assertIsInstance(home, unicode)
2204
2205
    def test_posix_home_ascii(self):
2206
        self.overrideEnv('HOME', '/home/test')
2207
        home = osutils._posix_get_home_dir()
2208
        self.assertIsInstance(home, unicode)
2209
        self.assertEqual(u'/home/test', home)
2210
2211
    def test_posix_home_unicode(self):
2212
        self.requireFeature(features.ByteStringNamedFilesystem)
2213
        self.overrideEnv('HOME', '/home/\xa7test')
2214
        self.overrideAttr(osutils, "_fs_enc", "iso8859-1")
2215
        self.assertEqual(u'/home/\xa7test', osutils._posix_get_home_dir())
2216
        osutils._fs_enc = "iso8859-5"
2217
        self.assertEqual(u'/home/\u0407test', osutils._posix_get_home_dir())
2218
        osutils._fs_enc = "utf-8"
2219
        self.assertRaises(errors.BadFilenameEncoding,
2220
            osutils._posix_get_home_dir)
2221
2222
5187.2.8 by Parth Malwankar
added tests for getuser_unicode
2223
class TestGetuserUnicode(tests.TestCase):
2224
6421.1.2 by Martin Packman
Fix tests for osutils.getuser_unicode now it uses the existing win32utils function
2225
    def test_is_unicode(self):
2226
        user = osutils.getuser_unicode()
2227
        self.assertIsInstance(user, unicode)
2228
6421.1.3 by Martin Packman
Factor out to test helper details on platform username retrieval
2229
    def envvar_to_override(self):
2230
        if sys.platform == "win32":
2231
            # Disable use of platform calls on windows so envvar is used
2232
            self.overrideAttr(win32utils, 'has_ctypes', False)
2233
            return 'USERNAME' # only variable used on windows
2234
        return 'LOGNAME' # first variable checked by getpass.getuser()
2235
5187.2.8 by Parth Malwankar
added tests for getuser_unicode
2236
    def test_ascii_user(self):
6421.1.3 by Martin Packman
Factor out to test helper details on platform username retrieval
2237
        self.overrideEnv(self.envvar_to_override(), 'jrandom')
5187.2.8 by Parth Malwankar
added tests for getuser_unicode
2238
        self.assertEqual(u'jrandom', osutils.getuser_unicode())
2239
2240
    def test_unicode_user(self):
2241
        ue = osutils.get_user_encoding()
5050.37.1 by Andrew Bennetts
Some fixes for tests that did not cope with LANG=C.
2242
        uni_val, env_val = tests.probe_unicode_in_user_encoding()
2243
        if uni_val is None:
2244
            raise tests.TestSkipped(
2245
                'Cannot find a unicode character that works in encoding %s'
2246
                % (osutils.get_user_encoding(),))
2247
        uni_username = u'jrandom' + uni_val
2248
        encoded_username = uni_username.encode(ue)
6421.1.4 by Martin Packman
Remove redundant and unsafe non-probed value in unicode getuser test
2249
        self.overrideEnv(self.envvar_to_override(), encoded_username)
5050.37.1 by Andrew Bennetts
Some fixes for tests that did not cope with LANG=C.
2250
        self.assertEqual(uni_username, osutils.getuser_unicode())
5609.47.2 by Alexander Belchenko
getuser_unicode: catch "ImportError: No module named pwd" on Windows when bzr is running as a service.
2251
2252
5409.5.3 by Vincent Ladeuil
Implement osutils.available_backup_name.
2253
class TestBackupNames(tests.TestCase):
2254
2255
    def setUp(self):
2256
        super(TestBackupNames, self).setUp()
2257
        self.backups = []
2258
2259
    def backup_exists(self, name):
2260
        return name in self.backups
2261
2262
    def available_backup_name(self, name):
2263
        backup_name = osutils.available_backup_name(name, self.backup_exists)
2264
        self.backups.append(backup_name)
2265
        return backup_name
2266
2267
    def assertBackupName(self, expected, name):
2268
        self.assertEqual(expected, self.available_backup_name(name))
2269
2270
    def test_empty(self):
2271
        self.assertBackupName('file.~1~', 'file')
2272
2273
    def test_existing(self):
2274
        self.available_backup_name('file')
2275
        self.available_backup_name('file')
2276
        self.assertBackupName('file.~3~', 'file')
2277
        # Empty slots are found, this is not a strict requirement and may be
2278
        # revisited if we test against all implementations.
2279
        self.backups.remove('file.~2~')
2280
        self.assertBackupName('file.~2~', 'file')
5321.1.79 by Gordon Tyler
Added is_executable_on_path to osutils based on _probe from ExecutableFeature.
2281
2282
5321.1.80 by Gordon Tyler
Changed is_executable_on_path to find_executable_on_path to make it more useful.
2283
class TestFindExecutableInPath(tests.TestCase):
5321.2.1 by Vincent Ladeuil
Fix style issues, including vertical spaces, lines too long and multi lines imports.
2284
5321.1.79 by Gordon Tyler
Added is_executable_on_path to osutils based on _probe from ExecutableFeature.
2285
    def test_windows(self):
2286
        if sys.platform != 'win32':
2287
            raise tests.TestSkipped('test requires win32')
5321.1.80 by Gordon Tyler
Changed is_executable_on_path to find_executable_on_path to make it more useful.
2288
        self.assertTrue(osutils.find_executable_on_path('explorer') is not None)
5321.1.106 by Gordon Tyler
Fixed find_executable_on_path to properly test for executable-ness on win32 and not split the PATH for each extension in PATHEXT.
2289
        self.assertTrue(
2290
            osutils.find_executable_on_path('explorer.exe') is not None)
2291
        self.assertTrue(
2292
            osutils.find_executable_on_path('EXPLORER.EXE') is not None)
5321.1.80 by Gordon Tyler
Changed is_executable_on_path to find_executable_on_path to make it more useful.
2293
        self.assertTrue(
2294
            osutils.find_executable_on_path('THIS SHOULD NOT EXIST') is None)
5321.1.106 by Gordon Tyler
Fixed find_executable_on_path to properly test for executable-ness on win32 and not split the PATH for each extension in PATHEXT.
2295
        self.assertTrue(osutils.find_executable_on_path('file.txt') is None)
6437.44.1 by Gordon Tyler
Backport of fix for bug 939605 to bzr 2.5 series.
2296
        
2297
    def test_windows_app_path(self):
2298
        if sys.platform != 'win32':
2299
            raise tests.TestSkipped('test requires win32')
2300
        # Override PATH env var so that exe can only be found on App Path
2301
        self.overrideEnv('PATH', '')
2302
        # Internt Explorer is always registered in the App Path
2303
        self.assertTrue(osutils.find_executable_on_path('iexplore') is not None)
5321.1.79 by Gordon Tyler
Added is_executable_on_path to osutils based on _probe from ExecutableFeature.
2304
2305
    def test_other(self):
2306
        if sys.platform == 'win32':
2307
            raise tests.TestSkipped('test requires non-win32')
5321.2.2 by Vincent Ladeuil
Fix failing test.
2308
        self.assertTrue(osutils.find_executable_on_path('sh') is not None)
5321.1.80 by Gordon Tyler
Changed is_executable_on_path to find_executable_on_path to make it more useful.
2309
        self.assertTrue(
5321.2.2 by Vincent Ladeuil
Fix failing test.
2310
            osutils.find_executable_on_path('THIS SHOULD NOT EXIST') is None)
6336.2.1 by Martin Packman
Add is_environment_error() and switch trace to using it
2311
2312
2313
class TestEnvironmentErrors(tests.TestCase):
2314
    """Test handling of environmental errors"""
2315
2316
    def test_is_oserror(self):
2317
        self.assertTrue(osutils.is_environment_error(
2318
            OSError(errno.EINVAL, "Invalid parameter")))
2319
2320
    def test_is_ioerror(self):
2321
        self.assertTrue(osutils.is_environment_error(
2322
            IOError(errno.EINVAL, "Invalid parameter")))
2323
2324
    def test_is_socket_error(self):
2325
        self.assertTrue(osutils.is_environment_error(
2326
            socket.error(errno.EINVAL, "Invalid parameter")))
2327
2328
    def test_is_select_error(self):
2329
        self.assertTrue(osutils.is_environment_error(
2330
            select.error(errno.EINVAL, "Invalid parameter")))
2331
2332
    def test_is_pywintypes_error(self):
2333
        self.requireFeature(features.pywintypes)
2334
        import pywintypes
2335
        self.assertTrue(osutils.is_environment_error(
2336
            pywintypes.error(errno.EINVAL, "Invalid parameter", "Caller")))