102
78
self.assertEqual(type(result), str)
103
79
self.assertContainsRe(result, r'^[a-z0-9]{100}$')
105
def test_is_inside(self):
106
is_inside = osutils.is_inside
107
self.assertTrue(is_inside('src', 'src/foo.c'))
108
self.assertFalse(is_inside('src', 'srccontrol'))
109
self.assertTrue(is_inside('src', 'src/a/a/a/foo.c'))
110
self.assertTrue(is_inside('foo.c', 'foo.c'))
111
self.assertFalse(is_inside('foo.c', ''))
112
self.assertTrue(is_inside('', 'foo.c'))
114
def test_is_inside_any(self):
115
SRC_FOO_C = pathjoin('src', 'foo.c')
116
for dirs, fn in [(['src', 'doc'], SRC_FOO_C),
117
(['src'], SRC_FOO_C),
120
self.assert_(is_inside_any(dirs, fn))
121
for dirs, fn in [(['src'], 'srccontrol'),
122
(['src'], 'srccontrol/foo')]:
123
self.assertFalse(is_inside_any(dirs, fn))
125
def test_is_inside_or_parent_of_any(self):
126
for dirs, fn in [(['src', 'doc'], 'src/foo.c'),
127
(['src'], 'src/foo.c'),
128
(['src/bar.c'], 'src'),
129
(['src/bar.c', 'bla/foo.c'], 'src'),
132
self.assert_(is_inside_or_parent_of_any(dirs, fn))
134
for dirs, fn in [(['src'], 'srccontrol'),
135
(['srccontrol/foo.c'], 'src'),
136
(['src'], 'srccontrol/foo')]:
137
self.assertFalse(is_inside_or_parent_of_any(dirs, fn))
139
82
def test_rmtree(self):
140
83
# Check to remove tree with read-only files/dirs
214
151
os.umask(orig_umask)
216
def assertFormatedDelta(self, expected, seconds):
217
"""Assert osutils.format_delta formats as expected"""
218
actual = osutils.format_delta(seconds)
219
self.assertEqual(expected, actual)
221
def test_format_delta(self):
222
self.assertFormatedDelta('0 seconds ago', 0)
223
self.assertFormatedDelta('1 second ago', 1)
224
self.assertFormatedDelta('10 seconds ago', 10)
225
self.assertFormatedDelta('59 seconds ago', 59)
226
self.assertFormatedDelta('89 seconds ago', 89)
227
self.assertFormatedDelta('1 minute, 30 seconds ago', 90)
228
self.assertFormatedDelta('3 minutes, 0 seconds ago', 180)
229
self.assertFormatedDelta('3 minutes, 1 second ago', 181)
230
self.assertFormatedDelta('10 minutes, 15 seconds ago', 615)
231
self.assertFormatedDelta('30 minutes, 59 seconds ago', 1859)
232
self.assertFormatedDelta('31 minutes, 0 seconds ago', 1860)
233
self.assertFormatedDelta('60 minutes, 0 seconds ago', 3600)
234
self.assertFormatedDelta('89 minutes, 59 seconds ago', 5399)
235
self.assertFormatedDelta('1 hour, 30 minutes ago', 5400)
236
self.assertFormatedDelta('2 hours, 30 minutes ago', 9017)
237
self.assertFormatedDelta('10 hours, 0 minutes ago', 36000)
238
self.assertFormatedDelta('24 hours, 0 minutes ago', 86400)
239
self.assertFormatedDelta('35 hours, 59 minutes ago', 129599)
240
self.assertFormatedDelta('36 hours, 0 minutes ago', 129600)
241
self.assertFormatedDelta('36 hours, 0 minutes ago', 129601)
242
self.assertFormatedDelta('36 hours, 1 minute ago', 129660)
243
self.assertFormatedDelta('36 hours, 1 minute ago', 129661)
244
self.assertFormatedDelta('84 hours, 10 minutes ago', 303002)
246
# We handle when time steps the wrong direction because computers
247
# don't have synchronized clocks.
248
self.assertFormatedDelta('84 hours, 10 minutes in the future', -303002)
249
self.assertFormatedDelta('1 second in the future', -1)
250
self.assertFormatedDelta('2 seconds in the future', -2)
252
def test_dereference_path(self):
253
if not osutils.has_symlinks():
254
raise TestSkipped('Symlinks are not supported on this platform')
255
cwd = osutils.realpath('.')
257
bar_path = osutils.pathjoin(cwd, 'bar')
258
# Using './' to avoid bug #1213894 (first path component not
259
# dereferenced) in Python 2.4.1 and earlier
260
self.assertEqual(bar_path, osutils.realpath('./bar'))
261
os.symlink('bar', 'foo')
262
self.assertEqual(bar_path, osutils.realpath('./foo'))
264
# Does not dereference terminal symlinks
265
foo_path = osutils.pathjoin(cwd, 'foo')
266
self.assertEqual(foo_path, osutils.dereference_path('./foo'))
268
# Dereferences parent symlinks
270
baz_path = osutils.pathjoin(bar_path, 'baz')
271
self.assertEqual(baz_path, osutils.dereference_path('./foo/baz'))
273
# Dereferences parent symlinks that are the first path element
274
self.assertEqual(baz_path, osutils.dereference_path('foo/baz'))
276
# Dereferences parent symlinks in absolute paths
277
foo_baz_path = osutils.pathjoin(foo_path, 'baz')
278
self.assertEqual(baz_path, osutils.dereference_path(foo_baz_path))
280
def test_changing_access(self):
281
f = file('file', 'w')
285
# Make a file readonly
286
osutils.make_readonly('file')
287
mode = osutils.lstat('file').st_mode
288
self.assertEqual(mode, mode & 0777555)
290
# Make a file writable
291
osutils.make_writable('file')
292
mode = osutils.lstat('file').st_mode
293
self.assertEqual(mode, mode | 0200)
295
if osutils.has_symlinks():
296
# should not error when handed a symlink
297
os.symlink('nonexistent', 'dangling')
298
osutils.make_readonly('dangling')
299
osutils.make_writable('dangling')
301
def test_kind_marker(self):
302
self.assertEqual("", osutils.kind_marker("file"))
303
self.assertEqual("/", osutils.kind_marker(osutils._directory_kind))
304
self.assertEqual("@", osutils.kind_marker("symlink"))
305
self.assertRaises(errors.BzrError, osutils.kind_marker, "unknown")
308
154
class TestSafeUnicode(TestCase):
328
class TestSafeUtf8(TestCase):
330
def test_from_ascii_string(self):
332
self.assertEqual('foobar', osutils.safe_utf8(f))
334
def test_from_unicode_string_ascii_contents(self):
335
self.assertEqual('bargam', osutils.safe_utf8(u'bargam'))
337
def test_from_unicode_string_unicode_contents(self):
338
self.assertEqual('bargam\xc2\xae', osutils.safe_utf8(u'bargam\xae'))
340
def test_from_utf8_string(self):
341
self.assertEqual('foo\xc2\xae', osutils.safe_utf8('foo\xc2\xae'))
343
def test_bad_utf8_string(self):
344
self.assertRaises(BzrBadParameterNotUnicode,
345
osutils.safe_utf8, '\xbb\xbb')
348
class TestSafeRevisionId(TestCase):
350
def test_from_ascii_string(self):
351
# this shouldn't give a warning because it's getting an ascii string
352
self.assertEqual('foobar', osutils.safe_revision_id('foobar'))
354
def test_from_unicode_string_ascii_contents(self):
355
self.assertEqual('bargam',
356
osutils.safe_revision_id(u'bargam', warn=False))
358
def test_from_unicode_deprecated(self):
359
self.assertEqual('bargam',
360
self.callDeprecated([osutils._revision_id_warning],
361
osutils.safe_revision_id, u'bargam'))
363
def test_from_unicode_string_unicode_contents(self):
364
self.assertEqual('bargam\xc2\xae',
365
osutils.safe_revision_id(u'bargam\xae', warn=False))
367
def test_from_utf8_string(self):
368
self.assertEqual('foo\xc2\xae',
369
osutils.safe_revision_id('foo\xc2\xae'))
372
"""Currently, None is a valid revision_id"""
373
self.assertEqual(None, osutils.safe_revision_id(None))
376
class TestSafeFileId(TestCase):
378
def test_from_ascii_string(self):
379
self.assertEqual('foobar', osutils.safe_file_id('foobar'))
381
def test_from_unicode_string_ascii_contents(self):
382
self.assertEqual('bargam', osutils.safe_file_id(u'bargam', warn=False))
384
def test_from_unicode_deprecated(self):
385
self.assertEqual('bargam',
386
self.callDeprecated([osutils._file_id_warning],
387
osutils.safe_file_id, u'bargam'))
389
def test_from_unicode_string_unicode_contents(self):
390
self.assertEqual('bargam\xc2\xae',
391
osutils.safe_file_id(u'bargam\xae', warn=False))
393
def test_from_utf8_string(self):
394
self.assertEqual('foo\xc2\xae',
395
osutils.safe_file_id('foo\xc2\xae'))
398
"""Currently, None is a valid revision_id"""
399
self.assertEqual(None, osutils.safe_file_id(None))
402
174
class TestWin32Funcs(TestCase):
403
175
"""Test that the _win32 versions of os utilities return appropriate paths."""
405
177
def test_abspath(self):
406
178
self.assertEqual('C:/foo', osutils._win32_abspath('C:\\foo'))
407
179
self.assertEqual('C:/foo', osutils._win32_abspath('C:/foo'))
408
self.assertEqual('//HOST/path', osutils._win32_abspath(r'\\HOST\path'))
409
self.assertEqual('//HOST/path', osutils._win32_abspath('//HOST/path'))
411
181
def test_realpath(self):
412
182
self.assertEqual('C:/foo', osutils._win32_realpath('C:\\foo'))
632
361
self.assertEqual(expected_dirblocks[1:],
633
362
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
635
def test__walkdirs_utf8(self):
644
self.build_tree(tree)
645
expected_dirblocks = [
647
[('0file', '0file', 'file'),
648
('1dir', '1dir', 'directory'),
649
('2file', '2file', 'file'),
653
[('1dir/0file', '0file', 'file'),
654
('1dir/1dir', '1dir', 'directory'),
657
(('1dir/1dir', './1dir/1dir'),
664
for dirdetail, dirblock in osutils._walkdirs_utf8('.'):
665
if len(dirblock) and dirblock[0][1] == '.bzr':
666
# this tests the filtering of selected paths
669
result.append((dirdetail, dirblock))
671
self.assertTrue(found_bzrdir)
672
self.assertEqual(expected_dirblocks,
673
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
674
# you can search a subdir only, with a supplied prefix.
676
for dirblock in osutils.walkdirs('./1dir', '1dir'):
677
result.append(dirblock)
678
self.assertEqual(expected_dirblocks[1:],
679
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
681
def _filter_out_stat(self, result):
682
"""Filter out the stat value from the walkdirs result"""
683
for dirdetail, dirblock in result:
685
for info in dirblock:
686
# Ignore info[3] which is the stat
687
new_dirblock.append((info[0], info[1], info[2], info[4]))
688
dirblock[:] = new_dirblock
690
def test_unicode_walkdirs(self):
691
"""Walkdirs should always return unicode paths."""
692
name0 = u'0file-\xb6'
693
name1 = u'1dir-\u062c\u0648'
694
name2 = u'2file-\u0633'
699
name1 + '/' + name1 + '/',
703
self.build_tree(tree)
705
raise TestSkipped('Could not represent Unicode chars'
706
' in current encoding.')
707
expected_dirblocks = [
709
[(name0, name0, 'file', './' + name0),
710
(name1, name1, 'directory', './' + name1),
711
(name2, name2, 'file', './' + name2),
714
((name1, './' + name1),
715
[(name1 + '/' + name0, name0, 'file', './' + name1
717
(name1 + '/' + name1, name1, 'directory', './' + name1
721
((name1 + '/' + name1, './' + name1 + '/' + name1),
726
result = list(osutils.walkdirs('.'))
727
self._filter_out_stat(result)
728
self.assertEqual(expected_dirblocks, result)
729
result = list(osutils.walkdirs(u'./'+name1, name1))
730
self._filter_out_stat(result)
731
self.assertEqual(expected_dirblocks[1:], result)
733
def test_unicode__walkdirs_utf8(self):
734
"""Walkdirs_utf8 should always return utf8 paths.
736
The abspath portion might be in unicode or utf-8
738
name0 = u'0file-\xb6'
739
name1 = u'1dir-\u062c\u0648'
740
name2 = u'2file-\u0633'
745
name1 + '/' + name1 + '/',
749
self.build_tree(tree)
751
raise TestSkipped('Could not represent Unicode chars'
752
' in current encoding.')
753
name0 = name0.encode('utf8')
754
name1 = name1.encode('utf8')
755
name2 = name2.encode('utf8')
757
expected_dirblocks = [
759
[(name0, name0, 'file', './' + name0),
760
(name1, name1, 'directory', './' + name1),
761
(name2, name2, 'file', './' + name2),
764
((name1, './' + name1),
765
[(name1 + '/' + name0, name0, 'file', './' + name1
767
(name1 + '/' + name1, name1, 'directory', './' + name1
771
((name1 + '/' + name1, './' + name1 + '/' + name1),
777
# For ease in testing, if walkdirs_utf8 returns Unicode, assert that
778
# all abspaths are Unicode, and encode them back into utf8.
779
for dirdetail, dirblock in osutils._walkdirs_utf8('.'):
780
self.assertIsInstance(dirdetail[0], str)
781
if isinstance(dirdetail[1], unicode):
782
dirdetail = (dirdetail[0], dirdetail[1].encode('utf8'))
783
dirblock = [list(info) for info in dirblock]
784
for info in dirblock:
785
self.assertIsInstance(info[4], unicode)
786
info[4] = info[4].encode('utf8')
788
for info in dirblock:
789
self.assertIsInstance(info[0], str)
790
self.assertIsInstance(info[1], str)
791
self.assertIsInstance(info[4], str)
792
# Remove the stat information
793
new_dirblock.append((info[0], info[1], info[2], info[4]))
794
result.append((dirdetail, new_dirblock))
795
self.assertEqual(expected_dirblocks, result)
797
def test_unicode__walkdirs_unicode_to_utf8(self):
798
"""walkdirs_unicode_to_utf8 should be a safe fallback everywhere
800
The abspath portion should be in unicode
802
name0u = u'0file-\xb6'
803
name1u = u'1dir-\u062c\u0648'
804
name2u = u'2file-\u0633'
808
name1u + '/' + name0u,
809
name1u + '/' + name1u + '/',
813
self.build_tree(tree)
815
raise TestSkipped('Could not represent Unicode chars'
816
' in current encoding.')
817
name0 = name0u.encode('utf8')
818
name1 = name1u.encode('utf8')
819
name2 = name2u.encode('utf8')
821
# All of the abspaths should be in unicode, all of the relative paths
823
expected_dirblocks = [
825
[(name0, name0, 'file', './' + name0u),
826
(name1, name1, 'directory', './' + name1u),
827
(name2, name2, 'file', './' + name2u),
830
((name1, './' + name1u),
831
[(name1 + '/' + name0, name0, 'file', './' + name1u
833
(name1 + '/' + name1, name1, 'directory', './' + name1u
837
((name1 + '/' + name1, './' + name1u + '/' + name1u),
842
result = list(osutils._walkdirs_unicode_to_utf8('.'))
843
self._filter_out_stat(result)
844
self.assertEqual(expected_dirblocks, result)
846
364
def assertPathCompare(self, path_less, path_greater):
847
365
"""check that path_less and path_greater compare correctly."""
848
366
self.assertEqual(0, osutils.compare_paths_prefix_order(
974
492
self.assertEqual([('source/lnk', 'target/lnk')], processed_links)
977
#class TestTerminalEncoding has been moved to test_osutils_encodings.py
978
# [bialix] 2006/12/26
981
class TestSetUnsetEnv(TestCase):
982
"""Test updating the environment"""
495
class TestTerminalEncoding(TestCase):
496
"""Test the auto-detection of proper terminal encoding."""
985
super(TestSetUnsetEnv, self).setUp()
987
self.assertEqual(None, os.environ.get('BZR_TEST_ENV_VAR'),
988
'Environment was not cleaned up properly.'
989
' Variable BZR_TEST_ENV_VAR should not exist.')
991
if 'BZR_TEST_ENV_VAR' in os.environ:
992
del os.environ['BZR_TEST_ENV_VAR']
994
self.addCleanup(cleanup)
997
"""Test that we can set an env variable"""
998
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
999
self.assertEqual(None, old)
1000
self.assertEqual('foo', os.environ.get('BZR_TEST_ENV_VAR'))
1002
def test_double_set(self):
1003
"""Test that we get the old value out"""
1004
osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
1005
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'bar')
1006
self.assertEqual('foo', old)
1007
self.assertEqual('bar', os.environ.get('BZR_TEST_ENV_VAR'))
1009
def test_unicode(self):
1010
"""Environment can only contain plain strings
1012
So Unicode strings must be encoded.
1014
uni_val, env_val = probe_unicode_in_user_encoding()
1016
raise TestSkipped('Cannot find a unicode character that works in'
1017
' encoding %s' % (bzrlib.user_encoding,))
1019
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', uni_val)
1020
self.assertEqual(env_val, os.environ.get('BZR_TEST_ENV_VAR'))
1022
def test_unset(self):
1023
"""Test that passing None will remove the env var"""
1024
osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
1025
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', None)
1026
self.assertEqual('foo', old)
1027
self.assertEqual(None, os.environ.get('BZR_TEST_ENV_VAR'))
1028
self.failIf('BZR_TEST_ENV_VAR' in os.environ)
1031
class TestLocalTimeOffset(TestCase):
1033
def test_local_time_offset(self):
1034
"""Test that local_time_offset() returns a sane value."""
1035
offset = osutils.local_time_offset()
1036
self.assertTrue(isinstance(offset, int))
1037
# Test that the offset is no more than a eighteen hours in
1039
# Time zone handling is system specific, so it is difficult to
1040
# do more specific tests, but a value outside of this range is
1042
eighteen_hours = 18 * 3600
1043
self.assertTrue(-eighteen_hours < offset < eighteen_hours)
1045
def test_local_time_offset_with_timestamp(self):
1046
"""Test that local_time_offset() works with a timestamp."""
1047
offset = osutils.local_time_offset(1000000000.1234567)
1048
self.assertTrue(isinstance(offset, int))
1049
eighteen_hours = 18 * 3600
1050
self.assertTrue(-eighteen_hours < offset < eighteen_hours)
1053
class TestShaFileByName(TestCaseInTempDir):
1055
def test_sha_empty(self):
1056
self.build_tree_contents([('foo', '')])
1057
expected_sha = osutils.sha_string('')
1058
self.assertEqual(expected_sha, osutils.sha_file_by_name('foo'))
1060
def test_sha_mixed_endings(self):
1061
text = 'test\r\nwith\nall\rpossible line endings\r\n'
1062
self.build_tree_contents([('foo', text)])
1063
expected_sha = osutils.sha_string(text)
1064
self.assertEqual(expected_sha, osutils.sha_file_by_name('foo'))
499
self._stdout = sys.stdout
500
self._stderr = sys.stderr
501
self._stdin = sys.stdin
502
self._user_encoding = bzrlib.user_encoding
504
self.addCleanup(self._reset)
506
sys.stdout = StringIOWrapper()
507
sys.stdout.encoding = 'stdout_encoding'
508
sys.stderr = StringIOWrapper()
509
sys.stderr.encoding = 'stderr_encoding'
510
sys.stdin = StringIOWrapper()
511
sys.stdin.encoding = 'stdin_encoding'
512
bzrlib.user_encoding = 'user_encoding'
515
sys.stdout = self._stdout
516
sys.stderr = self._stderr
517
sys.stdin = self._stdin
518
bzrlib.user_encoding = self._user_encoding
520
def test_get_terminal_encoding(self):
521
# first preference is stdout encoding
522
self.assertEqual('stdout_encoding', osutils.get_terminal_encoding())
524
sys.stdout.encoding = None
525
# if sys.stdout is None, fall back to sys.stdin
526
self.assertEqual('stdin_encoding', osutils.get_terminal_encoding())
528
sys.stdin.encoding = None
529
# and in the worst case, use bzrlib.user_encoding
530
self.assertEqual('user_encoding', osutils.get_terminal_encoding())