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