158
132
os.remove('socket')
160
def test_kind_marker(self):
161
self.assertEqual(osutils.kind_marker('file'), '')
162
self.assertEqual(osutils.kind_marker('directory'), '/')
163
self.assertEqual(osutils.kind_marker('symlink'), '@')
164
self.assertEqual(osutils.kind_marker('tree-reference'), '+')
166
def test_get_umask(self):
167
if sys.platform == 'win32':
168
# umask always returns '0', no way to set it
169
self.assertEqual(0, osutils.get_umask())
172
orig_umask = osutils.get_umask()
175
self.assertEqual(0222, osutils.get_umask())
177
self.assertEqual(0022, osutils.get_umask())
179
self.assertEqual(0002, osutils.get_umask())
181
self.assertEqual(0027, osutils.get_umask())
185
def assertFormatedDelta(self, expected, seconds):
186
"""Assert osutils.format_delta formats as expected"""
187
actual = osutils.format_delta(seconds)
188
self.assertEqual(expected, actual)
190
def test_format_delta(self):
191
self.assertFormatedDelta('0 seconds ago', 0)
192
self.assertFormatedDelta('1 second ago', 1)
193
self.assertFormatedDelta('10 seconds ago', 10)
194
self.assertFormatedDelta('59 seconds ago', 59)
195
self.assertFormatedDelta('89 seconds ago', 89)
196
self.assertFormatedDelta('1 minute, 30 seconds ago', 90)
197
self.assertFormatedDelta('3 minutes, 0 seconds ago', 180)
198
self.assertFormatedDelta('3 minutes, 1 second ago', 181)
199
self.assertFormatedDelta('10 minutes, 15 seconds ago', 615)
200
self.assertFormatedDelta('30 minutes, 59 seconds ago', 1859)
201
self.assertFormatedDelta('31 minutes, 0 seconds ago', 1860)
202
self.assertFormatedDelta('60 minutes, 0 seconds ago', 3600)
203
self.assertFormatedDelta('89 minutes, 59 seconds ago', 5399)
204
self.assertFormatedDelta('1 hour, 30 minutes ago', 5400)
205
self.assertFormatedDelta('2 hours, 30 minutes ago', 9017)
206
self.assertFormatedDelta('10 hours, 0 minutes ago', 36000)
207
self.assertFormatedDelta('24 hours, 0 minutes ago', 86400)
208
self.assertFormatedDelta('35 hours, 59 minutes ago', 129599)
209
self.assertFormatedDelta('36 hours, 0 minutes ago', 129600)
210
self.assertFormatedDelta('36 hours, 0 minutes ago', 129601)
211
self.assertFormatedDelta('36 hours, 1 minute ago', 129660)
212
self.assertFormatedDelta('36 hours, 1 minute ago', 129661)
213
self.assertFormatedDelta('84 hours, 10 minutes ago', 303002)
215
# We handle when time steps the wrong direction because computers
216
# don't have synchronized clocks.
217
self.assertFormatedDelta('84 hours, 10 minutes in the future', -303002)
218
self.assertFormatedDelta('1 second in the future', -1)
219
self.assertFormatedDelta('2 seconds in the future', -2)
221
def test_dereference_path(self):
222
if not osutils.has_symlinks():
223
raise TestSkipped('Symlinks are not supported on this platform')
224
cwd = osutils.realpath('.')
226
bar_path = osutils.pathjoin(cwd, 'bar')
227
# Using './' to avoid bug #1213894 (first path component not
228
# dereferenced) in Python 2.4.1 and earlier
229
self.assertEqual(bar_path, osutils.realpath('./bar'))
230
os.symlink('bar', 'foo')
231
self.assertEqual(bar_path, osutils.realpath('./foo'))
233
# Does not dereference terminal symlinks
234
foo_path = osutils.pathjoin(cwd, 'foo')
235
self.assertEqual(foo_path, osutils.dereference_path('./foo'))
237
# Dereferences parent symlinks
239
baz_path = osutils.pathjoin(bar_path, 'baz')
240
self.assertEqual(baz_path, osutils.dereference_path('./foo/baz'))
242
# Dereferences parent symlinks that are the first path element
243
self.assertEqual(baz_path, osutils.dereference_path('foo/baz'))
245
# Dereferences parent symlinks in absolute paths
246
foo_baz_path = osutils.pathjoin(foo_path, 'baz')
247
self.assertEqual(baz_path, osutils.dereference_path(foo_baz_path))
250
def test_changing_access(self):
251
f = file('file', 'w')
255
# Make a file readonly
256
osutils.make_readonly('file')
257
mode = osutils.lstat('file').st_mode
258
self.assertEqual(mode, mode & 0777555)
260
# Make a file writable
261
osutils.make_writable('file')
262
mode = osutils.lstat('file').st_mode
263
self.assertEqual(mode, mode | 0200)
265
if osutils.has_symlinks():
266
# should not error when handed a symlink
267
os.symlink('nonexistent', 'dangling')
268
osutils.make_readonly('dangling')
269
osutils.make_writable('dangling')
272
def test_kind_marker(self):
273
self.assertEqual("", osutils.kind_marker("file"))
274
self.assertEqual("/", osutils.kind_marker(osutils._directory_kind))
275
self.assertEqual("@", osutils.kind_marker("symlink"))
276
self.assertRaises(errors.BzrError, osutils.kind_marker, "unknown")
279
135
class TestSafeUnicode(TestCase):
299
class TestSafeUtf8(TestCase):
301
def test_from_ascii_string(self):
303
self.assertEqual('foobar', osutils.safe_utf8(f))
305
def test_from_unicode_string_ascii_contents(self):
306
self.assertEqual('bargam', osutils.safe_utf8(u'bargam'))
308
def test_from_unicode_string_unicode_contents(self):
309
self.assertEqual('bargam\xc2\xae', osutils.safe_utf8(u'bargam\xae'))
311
def test_from_utf8_string(self):
312
self.assertEqual('foo\xc2\xae', osutils.safe_utf8('foo\xc2\xae'))
314
def test_bad_utf8_string(self):
315
self.assertRaises(BzrBadParameterNotUnicode,
316
osutils.safe_utf8, '\xbb\xbb')
319
class TestSafeRevisionId(TestCase):
321
def test_from_ascii_string(self):
322
self.assertEqual('foobar', osutils.safe_revision_id('foobar'))
324
def test_from_unicode_string_ascii_contents(self):
325
self.assertEqual('bargam',
326
osutils.safe_revision_id(u'bargam', warn=False))
328
def test_from_unicode_deprecated(self):
329
self.assertEqual('bargam',
330
self.callDeprecated([osutils._revision_id_warning],
331
osutils.safe_revision_id, u'bargam'))
333
def test_from_unicode_string_unicode_contents(self):
334
self.assertEqual('bargam\xc2\xae',
335
osutils.safe_revision_id(u'bargam\xae', warn=False))
337
def test_from_utf8_string(self):
338
self.assertEqual('foo\xc2\xae',
339
osutils.safe_revision_id('foo\xc2\xae'))
342
"""Currently, None is a valid revision_id"""
343
self.assertEqual(None, osutils.safe_revision_id(None))
346
class TestSafeFileId(TestCase):
348
def test_from_ascii_string(self):
349
self.assertEqual('foobar', osutils.safe_file_id('foobar'))
351
def test_from_unicode_string_ascii_contents(self):
352
self.assertEqual('bargam', osutils.safe_file_id(u'bargam', warn=False))
354
def test_from_unicode_deprecated(self):
355
self.assertEqual('bargam',
356
self.callDeprecated([osutils._file_id_warning],
357
osutils.safe_file_id, u'bargam'))
359
def test_from_unicode_string_unicode_contents(self):
360
self.assertEqual('bargam\xc2\xae',
361
osutils.safe_file_id(u'bargam\xae', warn=False))
363
def test_from_utf8_string(self):
364
self.assertEqual('foo\xc2\xae',
365
osutils.safe_file_id('foo\xc2\xae'))
368
"""Currently, None is a valid revision_id"""
369
self.assertEqual(None, osutils.safe_file_id(None))
372
155
class TestWin32Funcs(TestCase):
373
156
"""Test that the _win32 versions of os utilities return appropriate paths."""
375
158
def test_abspath(self):
376
159
self.assertEqual('C:/foo', osutils._win32_abspath('C:\\foo'))
377
160
self.assertEqual('C:/foo', osutils._win32_abspath('C:/foo'))
378
self.assertEqual('//HOST/path', osutils._win32_abspath(r'\\HOST\path'))
379
self.assertEqual('//HOST/path', osutils._win32_abspath('//HOST/path'))
381
162
def test_realpath(self):
382
163
self.assertEqual('C:/foo', osutils._win32_realpath('C:\\foo'))
558
284
self.build_tree(tree)
559
285
expected_dirblocks = [
561
[('0file', '0file', 'file'),
562
('1dir', '1dir', 'directory'),
563
('2file', '2file', 'file'),
567
[('1dir/0file', '0file', 'file'),
568
('1dir/1dir', '1dir', 'directory'),
571
(('1dir/1dir', './1dir/1dir'),
578
for dirdetail, dirblock in osutils.walkdirs('.'):
579
if len(dirblock) and dirblock[0][1] == '.bzr':
580
# this tests the filtering of selected paths
583
result.append((dirdetail, dirblock))
585
self.assertTrue(found_bzrdir)
586
self.assertEqual(expected_dirblocks,
587
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
588
# you can search a subdir only, with a supplied prefix.
590
for dirblock in osutils.walkdirs('./1dir', '1dir'):
591
result.append(dirblock)
592
self.assertEqual(expected_dirblocks[1:],
593
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
595
def test__walkdirs_utf8(self):
604
self.build_tree(tree)
605
expected_dirblocks = [
607
[('0file', '0file', 'file'),
608
('1dir', '1dir', 'directory'),
609
('2file', '2file', 'file'),
613
[('1dir/0file', '0file', 'file'),
614
('1dir/1dir', '1dir', 'directory'),
617
(('1dir/1dir', './1dir/1dir'),
624
for dirdetail, dirblock in osutils._walkdirs_utf8('.'):
625
if len(dirblock) and dirblock[0][1] == '.bzr':
626
# this tests the filtering of selected paths
629
result.append((dirdetail, dirblock))
631
self.assertTrue(found_bzrdir)
632
self.assertEqual(expected_dirblocks,
633
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
634
# you can search a subdir only, with a supplied prefix.
636
for dirblock in osutils.walkdirs('./1dir', '1dir'):
637
result.append(dirblock)
638
self.assertEqual(expected_dirblocks[1:],
639
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
641
def _filter_out_stat(self, result):
642
"""Filter out the stat value from the walkdirs result"""
643
for dirdetail, dirblock in result:
645
for info in dirblock:
646
# Ignore info[3] which is the stat
647
new_dirblock.append((info[0], info[1], info[2], info[4]))
648
dirblock[:] = new_dirblock
650
def test_unicode_walkdirs(self):
651
"""Walkdirs should always return unicode paths."""
652
name0 = u'0file-\xb6'
653
name1 = u'1dir-\u062c\u0648'
654
name2 = u'2file-\u0633'
659
name1 + '/' + name1 + '/',
663
self.build_tree(tree)
665
raise TestSkipped('Could not represent Unicode chars'
666
' in current encoding.')
667
expected_dirblocks = [
669
[(name0, name0, 'file', './' + name0),
670
(name1, name1, 'directory', './' + name1),
671
(name2, name2, 'file', './' + name2),
674
((name1, './' + name1),
675
[(name1 + '/' + name0, name0, 'file', './' + name1
677
(name1 + '/' + name1, name1, 'directory', './' + name1
681
((name1 + '/' + name1, './' + name1 + '/' + name1),
686
result = list(osutils.walkdirs('.'))
687
self._filter_out_stat(result)
688
self.assertEqual(expected_dirblocks, result)
689
result = list(osutils.walkdirs(u'./'+name1, name1))
690
self._filter_out_stat(result)
691
self.assertEqual(expected_dirblocks[1:], result)
693
def test_unicode__walkdirs_utf8(self):
694
"""Walkdirs_utf8 should always return utf8 paths.
696
The abspath portion might be in unicode or utf-8
698
name0 = u'0file-\xb6'
699
name1 = u'1dir-\u062c\u0648'
700
name2 = u'2file-\u0633'
705
name1 + '/' + name1 + '/',
709
self.build_tree(tree)
711
raise TestSkipped('Could not represent Unicode chars'
712
' in current encoding.')
713
name0 = name0.encode('utf8')
714
name1 = name1.encode('utf8')
715
name2 = name2.encode('utf8')
717
expected_dirblocks = [
719
[(name0, name0, 'file', './' + name0),
720
(name1, name1, 'directory', './' + name1),
721
(name2, name2, 'file', './' + name2),
724
((name1, './' + name1),
725
[(name1 + '/' + name0, name0, 'file', './' + name1
727
(name1 + '/' + name1, name1, 'directory', './' + name1
731
((name1 + '/' + name1, './' + name1 + '/' + name1),
737
# For ease in testing, if walkdirs_utf8 returns Unicode, assert that
738
# all abspaths are Unicode, and encode them back into utf8.
739
for dirdetail, dirblock in osutils._walkdirs_utf8('.'):
740
self.assertIsInstance(dirdetail[0], str)
741
if isinstance(dirdetail[1], unicode):
742
dirdetail = (dirdetail[0], dirdetail[1].encode('utf8'))
743
dirblock = [list(info) for info in dirblock]
744
for info in dirblock:
745
self.assertIsInstance(info[4], unicode)
746
info[4] = info[4].encode('utf8')
748
for info in dirblock:
749
self.assertIsInstance(info[0], str)
750
self.assertIsInstance(info[1], str)
751
self.assertIsInstance(info[4], str)
752
# Remove the stat information
753
new_dirblock.append((info[0], info[1], info[2], info[4]))
754
result.append((dirdetail, new_dirblock))
755
self.assertEqual(expected_dirblocks, result)
757
def test_unicode__walkdirs_unicode_to_utf8(self):
758
"""walkdirs_unicode_to_utf8 should be a safe fallback everywhere
760
The abspath portion should be in unicode
762
name0u = u'0file-\xb6'
763
name1u = u'1dir-\u062c\u0648'
764
name2u = u'2file-\u0633'
768
name1u + '/' + name0u,
769
name1u + '/' + name1u + '/',
773
self.build_tree(tree)
775
raise TestSkipped('Could not represent Unicode chars'
776
' in current encoding.')
777
name0 = name0u.encode('utf8')
778
name1 = name1u.encode('utf8')
779
name2 = name2u.encode('utf8')
781
# All of the abspaths should be in unicode, all of the relative paths
783
expected_dirblocks = [
785
[(name0, name0, 'file', './' + name0u),
786
(name1, name1, 'directory', './' + name1u),
787
(name2, name2, 'file', './' + name2u),
790
((name1, './' + name1u),
791
[(name1 + '/' + name0, name0, 'file', './' + name1u
793
(name1 + '/' + name1, name1, 'directory', './' + name1u
797
((name1 + '/' + name1, './' + name1u + '/' + name1u),
802
result = list(osutils._walkdirs_unicode_to_utf8('.'))
803
self._filter_out_stat(result)
804
self.assertEqual(expected_dirblocks, result)
287
('0file', '0file', 'file'),
288
('1dir', '1dir', 'directory'),
289
('2file', '2file', 'file'),
292
('1dir/0file', '0file', 'file'),
293
('1dir/1dir', '1dir', 'directory'),
300
for dirblock in osutils.walkdirs('.'):
301
if len(dirblock) and dirblock[0][1] == '.bzr':
302
# this tests the filtering of selected paths
305
result.append(dirblock)
307
self.assertTrue(found_bzrdir)
308
self.assertEqual(expected_dirblocks,
309
[[line[0:3] for line in block] for block in result])
310
# you can search a subdir only, with a supplied prefix.
312
for dirblock in osutils.walkdirs('1dir', '1dir'):
313
result.append(dirblock)
314
self.assertEqual(expected_dirblocks[1:],
315
[[line[0:3] for line in block] for block in result])
806
317
def assertPathCompare(self, path_less, path_greater):
807
318
"""check that path_less and path_greater compare correctly."""
881
392
sorted(original_paths, cmp=osutils.compare_paths_prefix_order))
884
class TestCopyTree(TestCaseInTempDir):
886
def test_copy_basic_tree(self):
887
self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c'])
888
osutils.copy_tree('source', 'target')
889
self.assertEqual(['a', 'b'], sorted(os.listdir('target')))
890
self.assertEqual(['c'], os.listdir('target/b'))
892
def test_copy_tree_target_exists(self):
893
self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c',
895
osutils.copy_tree('source', 'target')
896
self.assertEqual(['a', 'b'], sorted(os.listdir('target')))
897
self.assertEqual(['c'], os.listdir('target/b'))
899
def test_copy_tree_symlinks(self):
900
if not osutils.has_symlinks():
902
self.build_tree(['source/'])
903
os.symlink('a/generic/path', 'source/lnk')
904
osutils.copy_tree('source', 'target')
905
self.assertEqual(['lnk'], os.listdir('target'))
906
self.assertEqual('a/generic/path', os.readlink('target/lnk'))
908
def test_copy_tree_handlers(self):
911
def file_handler(from_path, to_path):
912
processed_files.append(('f', from_path, to_path))
913
def dir_handler(from_path, to_path):
914
processed_files.append(('d', from_path, to_path))
915
def link_handler(from_path, to_path):
916
processed_links.append((from_path, to_path))
917
handlers = {'file':file_handler,
918
'directory':dir_handler,
919
'symlink':link_handler,
922
self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c'])
923
if osutils.has_symlinks():
924
os.symlink('a/generic/path', 'source/lnk')
925
osutils.copy_tree('source', 'target', handlers=handlers)
927
self.assertEqual([('d', 'source', 'target'),
928
('f', 'source/a', 'target/a'),
929
('d', 'source/b', 'target/b'),
930
('f', 'source/b/c', 'target/b/c'),
932
self.failIfExists('target')
933
if osutils.has_symlinks():
934
self.assertEqual([('source/lnk', 'target/lnk')], processed_links)
937
#class TestTerminalEncoding has been moved to test_osutils_encodings.py
938
# [bialix] 2006/12/26
941
class TestSetUnsetEnv(TestCase):
942
"""Test updating the environment"""
395
class TestTerminalEncoding(TestCase):
396
"""Test the auto-detection of proper terminal encoding."""
945
super(TestSetUnsetEnv, self).setUp()
947
self.assertEqual(None, os.environ.get('BZR_TEST_ENV_VAR'),
948
'Environment was not cleaned up properly.'
949
' Variable BZR_TEST_ENV_VAR should not exist.')
951
if 'BZR_TEST_ENV_VAR' in os.environ:
952
del os.environ['BZR_TEST_ENV_VAR']
954
self.addCleanup(cleanup)
957
"""Test that we can set an env variable"""
958
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
959
self.assertEqual(None, old)
960
self.assertEqual('foo', os.environ.get('BZR_TEST_ENV_VAR'))
962
def test_double_set(self):
963
"""Test that we get the old value out"""
964
osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
965
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'bar')
966
self.assertEqual('foo', old)
967
self.assertEqual('bar', os.environ.get('BZR_TEST_ENV_VAR'))
969
def test_unicode(self):
970
"""Environment can only contain plain strings
972
So Unicode strings must be encoded.
974
# Try a few different characters, to see if we can get
975
# one that will be valid in the user_encoding
976
possible_vals = [u'm\xb5', u'\xe1', u'\u0410']
977
for uni_val in possible_vals:
979
env_val = uni_val.encode(bzrlib.user_encoding)
980
except UnicodeEncodeError:
981
# Try a different character
986
raise TestSkipped('Cannot find a unicode character that works in'
987
' encoding %s' % (bzrlib.user_encoding,))
989
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', uni_val)
990
self.assertEqual(env_val, os.environ.get('BZR_TEST_ENV_VAR'))
992
def test_unset(self):
993
"""Test that passing None will remove the env var"""
994
osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
995
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', None)
996
self.assertEqual('foo', old)
997
self.assertEqual(None, os.environ.get('BZR_TEST_ENV_VAR'))
998
self.failIf('BZR_TEST_ENV_VAR' in os.environ)
1001
class TestLocalTimeOffset(TestCase):
1003
def test_local_time_offset(self):
1004
"""Test that local_time_offset() returns a sane value."""
1005
offset = osutils.local_time_offset()
1006
self.assertTrue(isinstance(offset, int))
1007
# Test that the offset is no more than a eighteen hours in
1009
# Time zone handling is system specific, so it is difficult to
1010
# do more specific tests, but a value outside of this range is
1012
eighteen_hours = 18 * 3600
1013
self.assertTrue(-eighteen_hours < offset < eighteen_hours)
1015
def test_local_time_offset_with_timestamp(self):
1016
"""Test that local_time_offset() works with a timestamp."""
1017
offset = osutils.local_time_offset(1000000000.1234567)
1018
self.assertTrue(isinstance(offset, int))
1019
eighteen_hours = 18 * 3600
1020
self.assertTrue(-eighteen_hours < offset < eighteen_hours)
399
self._stdout = sys.stdout
400
self._stderr = sys.stderr
401
self._stdin = sys.stdin
402
self._user_encoding = bzrlib.user_encoding
404
self.addCleanup(self._reset)
406
sys.stdout = StringIOWrapper()
407
sys.stdout.encoding = 'stdout_encoding'
408
sys.stderr = StringIOWrapper()
409
sys.stderr.encoding = 'stderr_encoding'
410
sys.stdin = StringIOWrapper()
411
sys.stdin.encoding = 'stdin_encoding'
412
bzrlib.user_encoding = 'user_encoding'
415
sys.stdout = self._stdout
416
sys.stderr = self._stderr
417
sys.stdin = self._stdin
418
bzrlib.user_encoding = self._user_encoding
420
def test_get_terminal_encoding(self):
421
# first preference is stdout encoding
422
self.assertEqual('stdout_encoding', osutils.get_terminal_encoding())
424
sys.stdout.encoding = None
425
# if sys.stdout is None, fall back to sys.stdin
426
self.assertEqual('stdin_encoding', osutils.get_terminal_encoding())
428
sys.stdin.encoding = None
429
# and in the worst case, use bzrlib.user_encoding
430
self.assertEqual('user_encoding', osutils.get_terminal_encoding())