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_kind_marker(self):
251
self.assertEqual("", osutils.kind_marker("file"))
252
self.assertEqual("/", osutils.kind_marker(osutils._directory_kind))
253
self.assertEqual("@", osutils.kind_marker("symlink"))
254
self.assertRaises(errors.BzrError, osutils.kind_marker, "unknown")
257
135
class TestSafeUnicode(TestCase):
277
class TestSafeUtf8(TestCase):
279
def test_from_ascii_string(self):
281
self.assertEqual('foobar', osutils.safe_utf8(f))
283
def test_from_unicode_string_ascii_contents(self):
284
self.assertEqual('bargam', osutils.safe_utf8(u'bargam'))
286
def test_from_unicode_string_unicode_contents(self):
287
self.assertEqual('bargam\xc2\xae', osutils.safe_utf8(u'bargam\xae'))
289
def test_from_utf8_string(self):
290
self.assertEqual('foo\xc2\xae', osutils.safe_utf8('foo\xc2\xae'))
292
def test_bad_utf8_string(self):
293
self.assertRaises(BzrBadParameterNotUnicode,
294
osutils.safe_utf8, '\xbb\xbb')
297
class TestSafeRevisionId(TestCase):
299
def test_from_ascii_string(self):
300
self.assertEqual('foobar', osutils.safe_revision_id('foobar'))
302
def test_from_unicode_string_ascii_contents(self):
303
self.assertEqual('bargam',
304
osutils.safe_revision_id(u'bargam', warn=False))
306
def test_from_unicode_deprecated(self):
307
self.assertEqual('bargam',
308
self.callDeprecated([osutils._revision_id_warning],
309
osutils.safe_revision_id, u'bargam'))
311
def test_from_unicode_string_unicode_contents(self):
312
self.assertEqual('bargam\xc2\xae',
313
osutils.safe_revision_id(u'bargam\xae', warn=False))
315
def test_from_utf8_string(self):
316
self.assertEqual('foo\xc2\xae',
317
osutils.safe_revision_id('foo\xc2\xae'))
320
"""Currently, None is a valid revision_id"""
321
self.assertEqual(None, osutils.safe_revision_id(None))
324
class TestSafeFileId(TestCase):
326
def test_from_ascii_string(self):
327
self.assertEqual('foobar', osutils.safe_file_id('foobar'))
329
def test_from_unicode_string_ascii_contents(self):
330
self.assertEqual('bargam', osutils.safe_file_id(u'bargam', warn=False))
332
def test_from_unicode_deprecated(self):
333
self.assertEqual('bargam',
334
self.callDeprecated([osutils._file_id_warning],
335
osutils.safe_file_id, u'bargam'))
337
def test_from_unicode_string_unicode_contents(self):
338
self.assertEqual('bargam\xc2\xae',
339
osutils.safe_file_id(u'bargam\xae', warn=False))
341
def test_from_utf8_string(self):
342
self.assertEqual('foo\xc2\xae',
343
osutils.safe_file_id('foo\xc2\xae'))
346
"""Currently, None is a valid revision_id"""
347
self.assertEqual(None, osutils.safe_file_id(None))
350
155
class TestWin32Funcs(TestCase):
351
156
"""Test that the _win32 versions of os utilities return appropriate paths."""
353
158
def test_abspath(self):
354
159
self.assertEqual('C:/foo', osutils._win32_abspath('C:\\foo'))
355
160
self.assertEqual('C:/foo', osutils._win32_abspath('C:/foo'))
356
self.assertEqual('//HOST/path', osutils._win32_abspath(r'\\HOST\path'))
357
self.assertEqual('//HOST/path', osutils._win32_abspath('//HOST/path'))
359
162
def test_realpath(self):
360
163
self.assertEqual('C:/foo', osutils._win32_realpath('C:\\foo'))
536
308
self.build_tree(tree)
537
309
expected_dirblocks = [
539
[('0file', '0file', 'file'),
540
('1dir', '1dir', 'directory'),
541
('2file', '2file', 'file'),
545
[('1dir/0file', '0file', 'file'),
546
('1dir/1dir', '1dir', 'directory'),
549
(('1dir/1dir', './1dir/1dir'),
556
for dirdetail, dirblock in osutils.walkdirs('.'):
557
if len(dirblock) and dirblock[0][1] == '.bzr':
558
# this tests the filtering of selected paths
561
result.append((dirdetail, dirblock))
563
self.assertTrue(found_bzrdir)
564
self.assertEqual(expected_dirblocks,
565
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
566
# you can search a subdir only, with a supplied prefix.
568
for dirblock in osutils.walkdirs('./1dir', '1dir'):
569
result.append(dirblock)
570
self.assertEqual(expected_dirblocks[1:],
571
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
573
def test__walkdirs_utf8(self):
582
self.build_tree(tree)
583
expected_dirblocks = [
585
[('0file', '0file', 'file'),
586
('1dir', '1dir', 'directory'),
587
('2file', '2file', 'file'),
591
[('1dir/0file', '0file', 'file'),
592
('1dir/1dir', '1dir', 'directory'),
595
(('1dir/1dir', './1dir/1dir'),
602
for dirdetail, dirblock in osutils._walkdirs_utf8('.'):
603
if len(dirblock) and dirblock[0][1] == '.bzr':
604
# this tests the filtering of selected paths
607
result.append((dirdetail, dirblock))
609
self.assertTrue(found_bzrdir)
610
self.assertEqual(expected_dirblocks,
611
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
612
# you can search a subdir only, with a supplied prefix.
614
for dirblock in osutils.walkdirs('./1dir', '1dir'):
615
result.append(dirblock)
616
self.assertEqual(expected_dirblocks[1:],
617
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
619
def _filter_out_stat(self, result):
620
"""Filter out the stat value from the walkdirs result"""
621
for dirdetail, dirblock in result:
623
for info in dirblock:
624
# Ignore info[3] which is the stat
625
new_dirblock.append((info[0], info[1], info[2], info[4]))
626
dirblock[:] = new_dirblock
628
def test_unicode_walkdirs(self):
629
"""Walkdirs should always return unicode paths."""
630
name0 = u'0file-\xb6'
631
name1 = u'1dir-\u062c\u0648'
632
name2 = u'2file-\u0633'
637
name1 + '/' + name1 + '/',
641
self.build_tree(tree)
643
raise TestSkipped('Could not represent Unicode chars'
644
' in current encoding.')
645
expected_dirblocks = [
647
[(name0, name0, 'file', './' + name0),
648
(name1, name1, 'directory', './' + name1),
649
(name2, name2, 'file', './' + name2),
652
((name1, './' + name1),
653
[(name1 + '/' + name0, name0, 'file', './' + name1
655
(name1 + '/' + name1, name1, 'directory', './' + name1
659
((name1 + '/' + name1, './' + name1 + '/' + name1),
664
result = list(osutils.walkdirs('.'))
665
self._filter_out_stat(result)
666
self.assertEqual(expected_dirblocks, result)
667
result = list(osutils.walkdirs(u'./'+name1, name1))
668
self._filter_out_stat(result)
669
self.assertEqual(expected_dirblocks[1:], result)
671
def test_unicode__walkdirs_utf8(self):
672
"""Walkdirs_utf8 should always return utf8 paths.
674
The abspath portion might be in unicode or utf-8
676
name0 = u'0file-\xb6'
677
name1 = u'1dir-\u062c\u0648'
678
name2 = u'2file-\u0633'
683
name1 + '/' + name1 + '/',
687
self.build_tree(tree)
689
raise TestSkipped('Could not represent Unicode chars'
690
' in current encoding.')
691
name0 = name0.encode('utf8')
692
name1 = name1.encode('utf8')
693
name2 = name2.encode('utf8')
695
expected_dirblocks = [
697
[(name0, name0, 'file', './' + name0),
698
(name1, name1, 'directory', './' + name1),
699
(name2, name2, 'file', './' + name2),
702
((name1, './' + name1),
703
[(name1 + '/' + name0, name0, 'file', './' + name1
705
(name1 + '/' + name1, name1, 'directory', './' + name1
709
((name1 + '/' + name1, './' + name1 + '/' + name1),
715
# For ease in testing, if walkdirs_utf8 returns Unicode, assert that
716
# all abspaths are Unicode, and encode them back into utf8.
717
for dirdetail, dirblock in osutils._walkdirs_utf8('.'):
718
self.assertIsInstance(dirdetail[0], str)
719
if isinstance(dirdetail[1], unicode):
720
dirdetail = (dirdetail[0], dirdetail[1].encode('utf8'))
721
dirblock = [list(info) for info in dirblock]
722
for info in dirblock:
723
self.assertIsInstance(info[4], unicode)
724
info[4] = info[4].encode('utf8')
726
for info in dirblock:
727
self.assertIsInstance(info[0], str)
728
self.assertIsInstance(info[1], str)
729
self.assertIsInstance(info[4], str)
730
# Remove the stat information
731
new_dirblock.append((info[0], info[1], info[2], info[4]))
732
result.append((dirdetail, new_dirblock))
733
self.assertEqual(expected_dirblocks, result)
735
def test_unicode__walkdirs_unicode_to_utf8(self):
736
"""walkdirs_unicode_to_utf8 should be a safe fallback everywhere
738
The abspath portion should be in unicode
740
name0u = u'0file-\xb6'
741
name1u = u'1dir-\u062c\u0648'
742
name2u = u'2file-\u0633'
746
name1u + '/' + name0u,
747
name1u + '/' + name1u + '/',
751
self.build_tree(tree)
753
raise TestSkipped('Could not represent Unicode chars'
754
' in current encoding.')
755
name0 = name0u.encode('utf8')
756
name1 = name1u.encode('utf8')
757
name2 = name2u.encode('utf8')
759
# All of the abspaths should be in unicode, all of the relative paths
761
expected_dirblocks = [
763
[(name0, name0, 'file', './' + name0u),
764
(name1, name1, 'directory', './' + name1u),
765
(name2, name2, 'file', './' + name2u),
768
((name1, './' + name1u),
769
[(name1 + '/' + name0, name0, 'file', './' + name1u
771
(name1 + '/' + name1, name1, 'directory', './' + name1u
775
((name1 + '/' + name1, './' + name1u + '/' + name1u),
780
result = list(osutils._walkdirs_unicode_to_utf8('.'))
781
self._filter_out_stat(result)
782
self.assertEqual(expected_dirblocks, result)
311
('0file', '0file', 'file'),
312
('1dir', '1dir', 'directory'),
313
('2file', '2file', 'file'),
316
('1dir/0file', '0file', 'file'),
317
('1dir/1dir', '1dir', 'directory'),
324
for dirblock in osutils.walkdirs('.'):
325
if len(dirblock) and dirblock[0][1] == '.bzr':
326
# this tests the filtering of selected paths
329
result.append(dirblock)
331
self.assertTrue(found_bzrdir)
332
self.assertEqual(expected_dirblocks,
333
[[line[0:3] for line in block] for block in result])
334
# you can search a subdir only, with a supplied prefix.
336
for dirblock in osutils.walkdirs('1dir', '1dir'):
337
result.append(dirblock)
338
self.assertEqual(expected_dirblocks[1:],
339
[[line[0:3] for line in block] for block in result])
784
341
def assertPathCompare(self, path_less, path_greater):
785
342
"""check that path_less and path_greater compare correctly."""
859
416
sorted(original_paths, cmp=osutils.compare_paths_prefix_order))
862
class TestCopyTree(TestCaseInTempDir):
864
def test_copy_basic_tree(self):
865
self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c'])
866
osutils.copy_tree('source', 'target')
867
self.assertEqual(['a', 'b'], sorted(os.listdir('target')))
868
self.assertEqual(['c'], os.listdir('target/b'))
870
def test_copy_tree_target_exists(self):
871
self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c',
873
osutils.copy_tree('source', 'target')
874
self.assertEqual(['a', 'b'], sorted(os.listdir('target')))
875
self.assertEqual(['c'], os.listdir('target/b'))
877
def test_copy_tree_symlinks(self):
878
if not osutils.has_symlinks():
880
self.build_tree(['source/'])
881
os.symlink('a/generic/path', 'source/lnk')
882
osutils.copy_tree('source', 'target')
883
self.assertEqual(['lnk'], os.listdir('target'))
884
self.assertEqual('a/generic/path', os.readlink('target/lnk'))
886
def test_copy_tree_handlers(self):
889
def file_handler(from_path, to_path):
890
processed_files.append(('f', from_path, to_path))
891
def dir_handler(from_path, to_path):
892
processed_files.append(('d', from_path, to_path))
893
def link_handler(from_path, to_path):
894
processed_links.append((from_path, to_path))
895
handlers = {'file':file_handler,
896
'directory':dir_handler,
897
'symlink':link_handler,
900
self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c'])
901
if osutils.has_symlinks():
902
os.symlink('a/generic/path', 'source/lnk')
903
osutils.copy_tree('source', 'target', handlers=handlers)
905
self.assertEqual([('d', 'source', 'target'),
906
('f', 'source/a', 'target/a'),
907
('d', 'source/b', 'target/b'),
908
('f', 'source/b/c', 'target/b/c'),
910
self.failIfExists('target')
911
if osutils.has_symlinks():
912
self.assertEqual([('source/lnk', 'target/lnk')], processed_links)
915
#class TestTerminalEncoding has been moved to test_osutils_encodings.py
916
# [bialix] 2006/12/26
919
class TestSetUnsetEnv(TestCase):
920
"""Test updating the environment"""
419
class TestTerminalEncoding(TestCase):
420
"""Test the auto-detection of proper terminal encoding."""
923
super(TestSetUnsetEnv, self).setUp()
925
self.assertEqual(None, os.environ.get('BZR_TEST_ENV_VAR'),
926
'Environment was not cleaned up properly.'
927
' Variable BZR_TEST_ENV_VAR should not exist.')
929
if 'BZR_TEST_ENV_VAR' in os.environ:
930
del os.environ['BZR_TEST_ENV_VAR']
932
self.addCleanup(cleanup)
935
"""Test that we can set an env variable"""
936
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
937
self.assertEqual(None, old)
938
self.assertEqual('foo', os.environ.get('BZR_TEST_ENV_VAR'))
940
def test_double_set(self):
941
"""Test that we get the old value out"""
942
osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
943
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'bar')
944
self.assertEqual('foo', old)
945
self.assertEqual('bar', os.environ.get('BZR_TEST_ENV_VAR'))
947
def test_unicode(self):
948
"""Environment can only contain plain strings
950
So Unicode strings must be encoded.
952
# Try a few different characters, to see if we can get
953
# one that will be valid in the user_encoding
954
possible_vals = [u'm\xb5', u'\xe1', u'\u0410']
955
for uni_val in possible_vals:
957
env_val = uni_val.encode(bzrlib.user_encoding)
958
except UnicodeEncodeError:
959
# Try a different character
964
raise TestSkipped('Cannot find a unicode character that works in'
965
' encoding %s' % (bzrlib.user_encoding,))
967
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', uni_val)
968
self.assertEqual(env_val, os.environ.get('BZR_TEST_ENV_VAR'))
970
def test_unset(self):
971
"""Test that passing None will remove the env var"""
972
osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
973
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', None)
974
self.assertEqual('foo', old)
975
self.assertEqual(None, os.environ.get('BZR_TEST_ENV_VAR'))
976
self.failIf('BZR_TEST_ENV_VAR' in os.environ)
979
class TestLocalTimeOffset(TestCase):
981
def test_local_time_offset(self):
982
"""Test that local_time_offset() returns a sane value."""
983
offset = osutils.local_time_offset()
984
self.assertTrue(isinstance(offset, int))
985
# Test that the offset is no more than a eighteen hours in
987
# Time zone handling is system specific, so it is difficult to
988
# do more specific tests, but a value outside of this range is
990
eighteen_hours = 18 * 3600
991
self.assertTrue(-eighteen_hours < offset < eighteen_hours)
993
def test_local_time_offset_with_timestamp(self):
994
"""Test that local_time_offset() works with a timestamp."""
995
offset = osutils.local_time_offset(1000000000.1234567)
996
self.assertTrue(isinstance(offset, int))
997
eighteen_hours = 18 * 3600
998
self.assertTrue(-eighteen_hours < offset < eighteen_hours)
423
self._stdout = sys.stdout
424
self._stderr = sys.stderr
425
self._stdin = sys.stdin
426
self._user_encoding = bzrlib.user_encoding
428
self.addCleanup(self._reset)
430
sys.stdout = StringIOWrapper()
431
sys.stdout.encoding = 'stdout_encoding'
432
sys.stderr = StringIOWrapper()
433
sys.stderr.encoding = 'stderr_encoding'
434
sys.stdin = StringIOWrapper()
435
sys.stdin.encoding = 'stdin_encoding'
436
bzrlib.user_encoding = 'user_encoding'
439
sys.stdout = self._stdout
440
sys.stderr = self._stderr
441
sys.stdin = self._stdin
442
bzrlib.user_encoding = self._user_encoding
444
def test_get_terminal_encoding(self):
445
# first preference is stdout encoding
446
self.assertEqual('stdout_encoding', osutils.get_terminal_encoding())
448
sys.stdout.encoding = None
449
# if sys.stdout is None, fall back to sys.stdin
450
self.assertEqual('stdin_encoding', osutils.get_terminal_encoding())
452
sys.stdin.encoding = None
453
# and in the worst case, use bzrlib.user_encoding
454
self.assertEqual('user_encoding', osutils.get_terminal_encoding())