/brz/remove-bazaar

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