1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
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.
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.
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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
"""Tests for the osutils wrapper."""
19
from cStringIO import StringIO
34
from bzrlib.errors import BzrBadParameterNotUnicode, InvalidURL
35
from bzrlib.osutils import (
37
is_inside_or_parent_of_any,
42
from bzrlib.tests import (
45
probe_unicode_in_user_encoding,
54
from bzrlib.tests.file_utils import (
57
from bzrlib.tests.test__walkdirs_win32 import Win32ReadDirFeature
60
def load_tests(standard_tests, module, loader):
61
"""Parameterize readdir tests."""
62
to_adapt, result = split_suite_by_re(standard_tests, "readdir")
63
adapter = TestScenarioApplier()
64
from bzrlib import _readdir_py
65
adapter.scenarios = [('python', {'read_dir': _readdir_py.read_dir})]
66
if ReadDirFeature.available():
67
adapter.scenarios.append(('pyrex',
68
{'read_dir': ReadDirFeature.read_dir}))
69
adapt_tests(to_adapt, adapter, result)
73
class _ReadDirFeature(Feature):
77
from bzrlib import _readdir_pyx
78
self.read_dir = _readdir_pyx.read_dir
83
def feature_name(self):
84
return 'bzrlib._readdir_pyx'
86
ReadDirFeature = _ReadDirFeature()
89
class TestOSUtils(TestCaseInTempDir):
91
def test_contains_whitespace(self):
92
self.failUnless(osutils.contains_whitespace(u' '))
93
self.failUnless(osutils.contains_whitespace(u'hello there'))
94
self.failUnless(osutils.contains_whitespace(u'hellothere\n'))
95
self.failUnless(osutils.contains_whitespace(u'hello\nthere'))
96
self.failUnless(osutils.contains_whitespace(u'hello\rthere'))
97
self.failUnless(osutils.contains_whitespace(u'hello\tthere'))
99
# \xa0 is "Non-breaking-space" which on some python locales thinks it
100
# is whitespace, but we do not.
101
self.failIf(osutils.contains_whitespace(u''))
102
self.failIf(osutils.contains_whitespace(u'hellothere'))
103
self.failIf(osutils.contains_whitespace(u'hello\xa0there'))
105
def test_fancy_rename(self):
106
# This should work everywhere
108
osutils.fancy_rename(a, b,
109
rename_func=os.rename,
110
unlink_func=os.unlink)
112
open('a', 'wb').write('something in a\n')
114
self.failIfExists('a')
115
self.failUnlessExists('b')
116
self.check_file_contents('b', 'something in a\n')
118
open('a', 'wb').write('new something in a\n')
121
self.check_file_contents('a', 'something in a\n')
123
def test_rename(self):
124
# Rename should be semi-atomic on all platforms
125
open('a', 'wb').write('something in a\n')
126
osutils.rename('a', 'b')
127
self.failIfExists('a')
128
self.failUnlessExists('b')
129
self.check_file_contents('b', 'something in a\n')
131
open('a', 'wb').write('new something in a\n')
132
osutils.rename('b', 'a')
134
self.check_file_contents('a', 'something in a\n')
136
# TODO: test fancy_rename using a MemoryTransport
138
def test_rename_change_case(self):
139
# on Windows we should be able to change filename case by rename
140
self.build_tree(['a', 'b/'])
141
osutils.rename('a', 'A')
142
osutils.rename('b', 'B')
143
# we can't use failUnlessExists on case-insensitive filesystem
144
# so try to check shape of the tree
145
shape = sorted(os.listdir('.'))
146
self.assertEquals(['A', 'B'], shape)
148
def test_01_rand_chars_empty(self):
149
result = osutils.rand_chars(0)
150
self.assertEqual(result, '')
152
def test_02_rand_chars_100(self):
153
result = osutils.rand_chars(100)
154
self.assertEqual(len(result), 100)
155
self.assertEqual(type(result), str)
156
self.assertContainsRe(result, r'^[a-z0-9]{100}$')
158
def test_is_inside(self):
159
is_inside = osutils.is_inside
160
self.assertTrue(is_inside('src', 'src/foo.c'))
161
self.assertFalse(is_inside('src', 'srccontrol'))
162
self.assertTrue(is_inside('src', 'src/a/a/a/foo.c'))
163
self.assertTrue(is_inside('foo.c', 'foo.c'))
164
self.assertFalse(is_inside('foo.c', ''))
165
self.assertTrue(is_inside('', 'foo.c'))
167
def test_is_inside_any(self):
168
SRC_FOO_C = pathjoin('src', 'foo.c')
169
for dirs, fn in [(['src', 'doc'], SRC_FOO_C),
170
(['src'], SRC_FOO_C),
173
self.assert_(is_inside_any(dirs, fn))
174
for dirs, fn in [(['src'], 'srccontrol'),
175
(['src'], 'srccontrol/foo')]:
176
self.assertFalse(is_inside_any(dirs, fn))
178
def test_is_inside_or_parent_of_any(self):
179
for dirs, fn in [(['src', 'doc'], 'src/foo.c'),
180
(['src'], 'src/foo.c'),
181
(['src/bar.c'], 'src'),
182
(['src/bar.c', 'bla/foo.c'], 'src'),
185
self.assert_(is_inside_or_parent_of_any(dirs, fn))
187
for dirs, fn in [(['src'], 'srccontrol'),
188
(['srccontrol/foo.c'], 'src'),
189
(['src'], 'srccontrol/foo')]:
190
self.assertFalse(is_inside_or_parent_of_any(dirs, fn))
192
def test_rmtree(self):
193
# Check to remove tree with read-only files/dirs
195
f = file('dir/file', 'w')
198
# would like to also try making the directory readonly, but at the
199
# moment python shutil.rmtree doesn't handle that properly - it would
200
# need to chmod the directory before removing things inside it - deferred
201
# for now -- mbp 20060505
202
# osutils.make_readonly('dir')
203
osutils.make_readonly('dir/file')
205
osutils.rmtree('dir')
207
self.failIfExists('dir/file')
208
self.failIfExists('dir')
210
def test_file_kind(self):
211
self.build_tree(['file', 'dir/'])
212
self.assertEquals('file', osutils.file_kind('file'))
213
self.assertEquals('directory', osutils.file_kind('dir/'))
214
if osutils.has_symlinks():
215
os.symlink('symlink', 'symlink')
216
self.assertEquals('symlink', osutils.file_kind('symlink'))
218
# TODO: jam 20060529 Test a block device
220
os.lstat('/dev/null')
222
if e.errno not in (errno.ENOENT,):
225
self.assertEquals('chardev', osutils.file_kind('/dev/null'))
227
mkfifo = getattr(os, 'mkfifo', None)
231
self.assertEquals('fifo', osutils.file_kind('fifo'))
235
AF_UNIX = getattr(socket, 'AF_UNIX', None)
237
s = socket.socket(AF_UNIX)
240
self.assertEquals('socket', osutils.file_kind('socket'))
244
def test_kind_marker(self):
245
self.assertEqual(osutils.kind_marker('file'), '')
246
self.assertEqual(osutils.kind_marker('directory'), '/')
247
self.assertEqual(osutils.kind_marker('symlink'), '@')
248
self.assertEqual(osutils.kind_marker('tree-reference'), '+')
250
def test_get_umask(self):
251
if sys.platform == 'win32':
252
# umask always returns '0', no way to set it
253
self.assertEqual(0, osutils.get_umask())
256
orig_umask = osutils.get_umask()
259
self.assertEqual(0222, osutils.get_umask())
261
self.assertEqual(0022, osutils.get_umask())
263
self.assertEqual(0002, osutils.get_umask())
265
self.assertEqual(0027, osutils.get_umask())
269
def assertFormatedDelta(self, expected, seconds):
270
"""Assert osutils.format_delta formats as expected"""
271
actual = osutils.format_delta(seconds)
272
self.assertEqual(expected, actual)
274
def test_format_delta(self):
275
self.assertFormatedDelta('0 seconds ago', 0)
276
self.assertFormatedDelta('1 second ago', 1)
277
self.assertFormatedDelta('10 seconds ago', 10)
278
self.assertFormatedDelta('59 seconds ago', 59)
279
self.assertFormatedDelta('89 seconds ago', 89)
280
self.assertFormatedDelta('1 minute, 30 seconds ago', 90)
281
self.assertFormatedDelta('3 minutes, 0 seconds ago', 180)
282
self.assertFormatedDelta('3 minutes, 1 second ago', 181)
283
self.assertFormatedDelta('10 minutes, 15 seconds ago', 615)
284
self.assertFormatedDelta('30 minutes, 59 seconds ago', 1859)
285
self.assertFormatedDelta('31 minutes, 0 seconds ago', 1860)
286
self.assertFormatedDelta('60 minutes, 0 seconds ago', 3600)
287
self.assertFormatedDelta('89 minutes, 59 seconds ago', 5399)
288
self.assertFormatedDelta('1 hour, 30 minutes ago', 5400)
289
self.assertFormatedDelta('2 hours, 30 minutes ago', 9017)
290
self.assertFormatedDelta('10 hours, 0 minutes ago', 36000)
291
self.assertFormatedDelta('24 hours, 0 minutes ago', 86400)
292
self.assertFormatedDelta('35 hours, 59 minutes ago', 129599)
293
self.assertFormatedDelta('36 hours, 0 minutes ago', 129600)
294
self.assertFormatedDelta('36 hours, 0 minutes ago', 129601)
295
self.assertFormatedDelta('36 hours, 1 minute ago', 129660)
296
self.assertFormatedDelta('36 hours, 1 minute ago', 129661)
297
self.assertFormatedDelta('84 hours, 10 minutes ago', 303002)
299
# We handle when time steps the wrong direction because computers
300
# don't have synchronized clocks.
301
self.assertFormatedDelta('84 hours, 10 minutes in the future', -303002)
302
self.assertFormatedDelta('1 second in the future', -1)
303
self.assertFormatedDelta('2 seconds in the future', -2)
305
def test_format_date(self):
306
self.assertRaises(errors.UnsupportedTimezoneFormat,
307
osutils.format_date, 0, timezone='foo')
309
def test_dereference_path(self):
310
self.requireFeature(SymlinkFeature)
311
cwd = osutils.realpath('.')
313
bar_path = osutils.pathjoin(cwd, 'bar')
314
# Using './' to avoid bug #1213894 (first path component not
315
# dereferenced) in Python 2.4.1 and earlier
316
self.assertEqual(bar_path, osutils.realpath('./bar'))
317
os.symlink('bar', 'foo')
318
self.assertEqual(bar_path, osutils.realpath('./foo'))
320
# Does not dereference terminal symlinks
321
foo_path = osutils.pathjoin(cwd, 'foo')
322
self.assertEqual(foo_path, osutils.dereference_path('./foo'))
324
# Dereferences parent symlinks
326
baz_path = osutils.pathjoin(bar_path, 'baz')
327
self.assertEqual(baz_path, osutils.dereference_path('./foo/baz'))
329
# Dereferences parent symlinks that are the first path element
330
self.assertEqual(baz_path, osutils.dereference_path('foo/baz'))
332
# Dereferences parent symlinks in absolute paths
333
foo_baz_path = osutils.pathjoin(foo_path, 'baz')
334
self.assertEqual(baz_path, osutils.dereference_path(foo_baz_path))
336
def test_changing_access(self):
337
f = file('file', 'w')
341
# Make a file readonly
342
osutils.make_readonly('file')
343
mode = os.lstat('file').st_mode
344
self.assertEqual(mode, mode & 0777555)
346
# Make a file writable
347
osutils.make_writable('file')
348
mode = os.lstat('file').st_mode
349
self.assertEqual(mode, mode | 0200)
351
if osutils.has_symlinks():
352
# should not error when handed a symlink
353
os.symlink('nonexistent', 'dangling')
354
osutils.make_readonly('dangling')
355
osutils.make_writable('dangling')
357
def test_kind_marker(self):
358
self.assertEqual("", osutils.kind_marker("file"))
359
self.assertEqual("/", osutils.kind_marker(osutils._directory_kind))
360
self.assertEqual("@", osutils.kind_marker("symlink"))
361
self.assertRaises(errors.BzrError, osutils.kind_marker, "unknown")
363
def test_host_os_dereferences_symlinks(self):
364
osutils.host_os_dereferences_symlinks()
367
class TestPumpFile(TestCase):
368
"""Test pumpfile method."""
370
# create a test datablock
371
self.block_size = 512
372
pattern = '0123456789ABCDEF'
373
self.test_data = pattern * (3 * self.block_size / len(pattern))
374
self.test_data_len = len(self.test_data)
376
def test_bracket_block_size(self):
377
"""Read data in blocks with the requested read size bracketing the
379
# make sure test data is larger than max read size
380
self.assertTrue(self.test_data_len > self.block_size)
382
from_file = FakeReadFile(self.test_data)
385
# read (max / 2) bytes and verify read size wasn't affected
386
num_bytes_to_read = self.block_size / 2
387
pumpfile(from_file, to_file, num_bytes_to_read, self.block_size)
388
self.assertEqual(from_file.get_max_read_size(), num_bytes_to_read)
389
self.assertEqual(from_file.get_read_count(), 1)
391
# read (max) bytes and verify read size wasn't affected
392
num_bytes_to_read = self.block_size
393
from_file.reset_read_count()
394
pumpfile(from_file, to_file, num_bytes_to_read, self.block_size)
395
self.assertEqual(from_file.get_max_read_size(), num_bytes_to_read)
396
self.assertEqual(from_file.get_read_count(), 1)
398
# read (max + 1) bytes and verify read size was limited
399
num_bytes_to_read = self.block_size + 1
400
from_file.reset_read_count()
401
pumpfile(from_file, to_file, num_bytes_to_read, self.block_size)
402
self.assertEqual(from_file.get_max_read_size(), self.block_size)
403
self.assertEqual(from_file.get_read_count(), 2)
405
# finish reading the rest of the data
406
num_bytes_to_read = self.test_data_len - to_file.tell()
407
pumpfile(from_file, to_file, num_bytes_to_read, self.block_size)
409
# report error if the data wasn't equal (we only report the size due
410
# to the length of the data)
411
response_data = to_file.getvalue()
412
if response_data != self.test_data:
413
message = "Data not equal. Expected %d bytes, received %d."
414
self.fail(message % (len(response_data), self.test_data_len))
416
def test_specified_size(self):
417
"""Request a transfer larger than the maximum block size and verify
418
that the maximum read doesn't exceed the block_size."""
419
# make sure test data is larger than max read size
420
self.assertTrue(self.test_data_len > self.block_size)
422
# retrieve data in blocks
423
from_file = FakeReadFile(self.test_data)
425
pumpfile(from_file, to_file, self.test_data_len, self.block_size)
427
# verify read size was equal to the maximum read size
428
self.assertTrue(from_file.get_max_read_size() > 0)
429
self.assertEqual(from_file.get_max_read_size(), self.block_size)
430
self.assertEqual(from_file.get_read_count(), 3)
432
# report error if the data wasn't equal (we only report the size due
433
# to the length of the data)
434
response_data = to_file.getvalue()
435
if response_data != self.test_data:
436
message = "Data not equal. Expected %d bytes, received %d."
437
self.fail(message % (len(response_data), self.test_data_len))
439
def test_to_eof(self):
440
"""Read to end-of-file and verify that the reads are not larger than
441
the maximum read size."""
442
# make sure test data is larger than max read size
443
self.assertTrue(self.test_data_len > self.block_size)
445
# retrieve data to EOF
446
from_file = FakeReadFile(self.test_data)
448
pumpfile(from_file, to_file, -1, self.block_size)
450
# verify read size was equal to the maximum read size
451
self.assertEqual(from_file.get_max_read_size(), self.block_size)
452
self.assertEqual(from_file.get_read_count(), 4)
454
# report error if the data wasn't equal (we only report the size due
455
# to the length of the data)
456
response_data = to_file.getvalue()
457
if response_data != self.test_data:
458
message = "Data not equal. Expected %d bytes, received %d."
459
self.fail(message % (len(response_data), self.test_data_len))
461
def test_defaults(self):
462
"""Verifies that the default arguments will read to EOF -- this
463
test verifies that any existing usages of pumpfile will not be broken
464
with this new version."""
465
# retrieve data using default (old) pumpfile method
466
from_file = FakeReadFile(self.test_data)
468
pumpfile(from_file, to_file)
470
# report error if the data wasn't equal (we only report the size due
471
# to the length of the data)
472
response_data = to_file.getvalue()
473
if response_data != self.test_data:
474
message = "Data not equal. Expected %d bytes, received %d."
475
self.fail(message % (len(response_data), self.test_data_len))
478
class TestPumpStringFile(TestCase):
480
def test_empty(self):
482
pump_string_file("", output)
483
self.assertEqual("", output.getvalue())
485
def test_more_than_segment_size(self):
487
pump_string_file("123456789", output, 2)
488
self.assertEqual("123456789", output.getvalue())
490
def test_segment_size(self):
492
pump_string_file("12", output, 2)
493
self.assertEqual("12", output.getvalue())
495
def test_segment_size_multiple(self):
497
pump_string_file("1234", output, 2)
498
self.assertEqual("1234", output.getvalue())
501
class TestSafeUnicode(TestCase):
503
def test_from_ascii_string(self):
504
self.assertEqual(u'foobar', osutils.safe_unicode('foobar'))
506
def test_from_unicode_string_ascii_contents(self):
507
self.assertEqual(u'bargam', osutils.safe_unicode(u'bargam'))
509
def test_from_unicode_string_unicode_contents(self):
510
self.assertEqual(u'bargam\xae', osutils.safe_unicode(u'bargam\xae'))
512
def test_from_utf8_string(self):
513
self.assertEqual(u'foo\xae', osutils.safe_unicode('foo\xc2\xae'))
515
def test_bad_utf8_string(self):
516
self.assertRaises(BzrBadParameterNotUnicode,
517
osutils.safe_unicode,
521
class TestSafeUtf8(TestCase):
523
def test_from_ascii_string(self):
525
self.assertEqual('foobar', osutils.safe_utf8(f))
527
def test_from_unicode_string_ascii_contents(self):
528
self.assertEqual('bargam', osutils.safe_utf8(u'bargam'))
530
def test_from_unicode_string_unicode_contents(self):
531
self.assertEqual('bargam\xc2\xae', osutils.safe_utf8(u'bargam\xae'))
533
def test_from_utf8_string(self):
534
self.assertEqual('foo\xc2\xae', osutils.safe_utf8('foo\xc2\xae'))
536
def test_bad_utf8_string(self):
537
self.assertRaises(BzrBadParameterNotUnicode,
538
osutils.safe_utf8, '\xbb\xbb')
541
class TestSafeRevisionId(TestCase):
543
def test_from_ascii_string(self):
544
# this shouldn't give a warning because it's getting an ascii string
545
self.assertEqual('foobar', osutils.safe_revision_id('foobar'))
547
def test_from_unicode_string_ascii_contents(self):
548
self.assertEqual('bargam',
549
osutils.safe_revision_id(u'bargam', warn=False))
551
def test_from_unicode_deprecated(self):
552
self.assertEqual('bargam',
553
self.callDeprecated([osutils._revision_id_warning],
554
osutils.safe_revision_id, u'bargam'))
556
def test_from_unicode_string_unicode_contents(self):
557
self.assertEqual('bargam\xc2\xae',
558
osutils.safe_revision_id(u'bargam\xae', warn=False))
560
def test_from_utf8_string(self):
561
self.assertEqual('foo\xc2\xae',
562
osutils.safe_revision_id('foo\xc2\xae'))
565
"""Currently, None is a valid revision_id"""
566
self.assertEqual(None, osutils.safe_revision_id(None))
569
class TestSafeFileId(TestCase):
571
def test_from_ascii_string(self):
572
self.assertEqual('foobar', osutils.safe_file_id('foobar'))
574
def test_from_unicode_string_ascii_contents(self):
575
self.assertEqual('bargam', osutils.safe_file_id(u'bargam', warn=False))
577
def test_from_unicode_deprecated(self):
578
self.assertEqual('bargam',
579
self.callDeprecated([osutils._file_id_warning],
580
osutils.safe_file_id, u'bargam'))
582
def test_from_unicode_string_unicode_contents(self):
583
self.assertEqual('bargam\xc2\xae',
584
osutils.safe_file_id(u'bargam\xae', warn=False))
586
def test_from_utf8_string(self):
587
self.assertEqual('foo\xc2\xae',
588
osutils.safe_file_id('foo\xc2\xae'))
591
"""Currently, None is a valid revision_id"""
592
self.assertEqual(None, osutils.safe_file_id(None))
595
class TestWin32Funcs(TestCase):
596
"""Test that the _win32 versions of os utilities return appropriate paths."""
598
def test_abspath(self):
599
self.assertEqual('C:/foo', osutils._win32_abspath('C:\\foo'))
600
self.assertEqual('C:/foo', osutils._win32_abspath('C:/foo'))
601
self.assertEqual('//HOST/path', osutils._win32_abspath(r'\\HOST\path'))
602
self.assertEqual('//HOST/path', osutils._win32_abspath('//HOST/path'))
604
def test_realpath(self):
605
self.assertEqual('C:/foo', osutils._win32_realpath('C:\\foo'))
606
self.assertEqual('C:/foo', osutils._win32_realpath('C:/foo'))
608
def test_pathjoin(self):
609
self.assertEqual('path/to/foo', osutils._win32_pathjoin('path', 'to', 'foo'))
610
self.assertEqual('C:/foo', osutils._win32_pathjoin('path\\to', 'C:\\foo'))
611
self.assertEqual('C:/foo', osutils._win32_pathjoin('path/to', 'C:/foo'))
612
self.assertEqual('path/to/foo', osutils._win32_pathjoin('path/to/', 'foo'))
613
self.assertEqual('/foo', osutils._win32_pathjoin('C:/path/to/', '/foo'))
614
self.assertEqual('/foo', osutils._win32_pathjoin('C:\\path\\to\\', '\\foo'))
616
def test_normpath(self):
617
self.assertEqual('path/to/foo', osutils._win32_normpath(r'path\\from\..\to\.\foo'))
618
self.assertEqual('path/to/foo', osutils._win32_normpath('path//from/../to/./foo'))
620
def test_getcwd(self):
621
cwd = osutils._win32_getcwd()
622
os_cwd = os.getcwdu()
623
self.assertEqual(os_cwd[1:].replace('\\', '/'), cwd[1:])
624
# win32 is inconsistent whether it returns lower or upper case
625
# and even if it was consistent the user might type the other
626
# so we force it to uppercase
627
# running python.exe under cmd.exe return capital C:\\
628
# running win32 python inside a cygwin shell returns lowercase
629
self.assertEqual(os_cwd[0].upper(), cwd[0])
631
def test_fixdrive(self):
632
self.assertEqual('H:/foo', osutils._win32_fixdrive('h:/foo'))
633
self.assertEqual('H:/foo', osutils._win32_fixdrive('H:/foo'))
634
self.assertEqual('C:\\foo', osutils._win32_fixdrive('c:\\foo'))
636
def test_win98_abspath(self):
638
self.assertEqual('C:/foo', osutils._win98_abspath('C:\\foo'))
639
self.assertEqual('C:/foo', osutils._win98_abspath('C:/foo'))
641
self.assertEqual('//HOST/path', osutils._win98_abspath(r'\\HOST\path'))
642
self.assertEqual('//HOST/path', osutils._win98_abspath('//HOST/path'))
644
cwd = osutils.getcwd().rstrip('/')
645
drive = osutils._nt_splitdrive(cwd)[0]
646
self.assertEqual(cwd+'/path', osutils._win98_abspath('path'))
647
self.assertEqual(drive+'/path', osutils._win98_abspath('/path'))
650
self.assertEqual(cwd+'/'+u, osutils._win98_abspath(u))
653
class TestWin32FuncsDirs(TestCaseInTempDir):
654
"""Test win32 functions that create files."""
656
def test_getcwd(self):
657
if win32utils.winver == 'Windows 98':
658
raise TestSkipped('Windows 98 cannot handle unicode filenames')
659
# Make sure getcwd can handle unicode filenames
663
raise TestSkipped("Unable to create Unicode filename")
666
# TODO: jam 20060427 This will probably fail on Mac OSX because
667
# it will change the normalization of B\xe5gfors
668
# Consider using a different unicode character, or make
669
# osutils.getcwd() renormalize the path.
670
self.assertEndsWith(osutils._win32_getcwd(), u'mu-\xb5')
672
def test_minimum_path_selection(self):
673
self.assertEqual(set(),
674
osutils.minimum_path_selection([]))
675
self.assertEqual(set(['a', 'b']),
676
osutils.minimum_path_selection(['a', 'b']))
677
self.assertEqual(set(['a/', 'b']),
678
osutils.minimum_path_selection(['a/', 'b']))
679
self.assertEqual(set(['a/', 'b']),
680
osutils.minimum_path_selection(['a/c', 'a/', 'b']))
682
def test_mkdtemp(self):
683
tmpdir = osutils._win32_mkdtemp(dir='.')
684
self.assertFalse('\\' in tmpdir)
686
def test_rename(self):
694
osutils._win32_rename('b', 'a')
695
self.failUnlessExists('a')
696
self.failIfExists('b')
697
self.assertFileEqual('baz\n', 'a')
699
def test_rename_missing_file(self):
705
osutils._win32_rename('b', 'a')
706
except (IOError, OSError), e:
707
self.assertEqual(errno.ENOENT, e.errno)
708
self.assertFileEqual('foo\n', 'a')
710
def test_rename_missing_dir(self):
713
osutils._win32_rename('b', 'a')
714
except (IOError, OSError), e:
715
self.assertEqual(errno.ENOENT, e.errno)
717
def test_rename_current_dir(self):
720
# You can't rename the working directory
721
# doing rename non-existant . usually
722
# just raises ENOENT, since non-existant
725
osutils._win32_rename('b', '.')
726
except (IOError, OSError), e:
727
self.assertEqual(errno.ENOENT, e.errno)
729
def test_splitpath(self):
730
def check(expected, path):
731
self.assertEqual(expected, osutils.splitpath(path))
734
check(['a', 'b'], 'a/b')
735
check(['a', 'b'], 'a/./b')
736
check(['a', '.b'], 'a/.b')
737
check(['a', '.b'], 'a\\.b')
739
self.assertRaises(errors.BzrError, osutils.splitpath, 'a/../b')
742
class TestMacFuncsDirs(TestCaseInTempDir):
743
"""Test mac special functions that require directories."""
745
def test_getcwd(self):
746
# On Mac, this will actually create Ba\u030agfors
747
# but chdir will still work, because it accepts both paths
749
os.mkdir(u'B\xe5gfors')
751
raise TestSkipped("Unable to create Unicode filename")
753
os.chdir(u'B\xe5gfors')
754
self.assertEndsWith(osutils._mac_getcwd(), u'B\xe5gfors')
756
def test_getcwd_nonnorm(self):
757
# Test that _mac_getcwd() will normalize this path
759
os.mkdir(u'Ba\u030agfors')
761
raise TestSkipped("Unable to create Unicode filename")
763
os.chdir(u'Ba\u030agfors')
764
self.assertEndsWith(osutils._mac_getcwd(), u'B\xe5gfors')
767
class TestSplitLines(TestCase):
769
def test_split_unicode(self):
770
self.assertEqual([u'foo\n', u'bar\xae'],
771
osutils.split_lines(u'foo\nbar\xae'))
772
self.assertEqual([u'foo\n', u'bar\xae\n'],
773
osutils.split_lines(u'foo\nbar\xae\n'))
775
def test_split_with_carriage_returns(self):
776
self.assertEqual(['foo\rbar\n'],
777
osutils.split_lines('foo\rbar\n'))
780
class TestWalkDirs(TestCaseInTempDir):
782
def test_readdir(self):
791
self.build_tree(tree)
792
expected_names = ['.bzr', '0file', '1dir', '2file']
793
# read_dir returns pairs, which form a table with either None in all
794
# the first columns, or a sort key to get best on-disk-read order,
795
# and the disk path name in utf-8 encoding in the second column.
796
read_result = self.read_dir('.')
797
# The second column is always the names, and every name except "." and
798
# ".." should be present.
799
names = sorted([row[1] for row in read_result])
800
self.assertEqual(expected_names, names)
801
expected_sort_key = None
802
if read_result[0][0] is None:
803
# No sort key returned - all keys must None
804
operator = self.assertEqual
806
# A sort key in the first row implies sort keys in the other rows.
807
operator = self.assertNotEqual
808
for row in read_result:
809
operator(None, row[0])
811
def test_compiled_extension_exists(self):
812
self.requireFeature(ReadDirFeature)
814
def test_walkdirs(self):
823
self.build_tree(tree)
824
expected_dirblocks = [
826
[('0file', '0file', 'file'),
827
('1dir', '1dir', 'directory'),
828
('2file', '2file', 'file'),
832
[('1dir/0file', '0file', 'file'),
833
('1dir/1dir', '1dir', 'directory'),
836
(('1dir/1dir', './1dir/1dir'),
843
for dirdetail, dirblock in osutils.walkdirs('.'):
844
if len(dirblock) and dirblock[0][1] == '.bzr':
845
# this tests the filtering of selected paths
848
result.append((dirdetail, dirblock))
850
self.assertTrue(found_bzrdir)
851
self.assertEqual(expected_dirblocks,
852
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
853
# you can search a subdir only, with a supplied prefix.
855
for dirblock in osutils.walkdirs('./1dir', '1dir'):
856
result.append(dirblock)
857
self.assertEqual(expected_dirblocks[1:],
858
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
860
def test__walkdirs_utf8(self):
869
self.build_tree(tree)
870
expected_dirblocks = [
872
[('0file', '0file', 'file'),
873
('1dir', '1dir', 'directory'),
874
('2file', '2file', 'file'),
878
[('1dir/0file', '0file', 'file'),
879
('1dir/1dir', '1dir', 'directory'),
882
(('1dir/1dir', './1dir/1dir'),
889
for dirdetail, dirblock in osutils._walkdirs_utf8('.'):
890
if len(dirblock) and dirblock[0][1] == '.bzr':
891
# this tests the filtering of selected paths
894
result.append((dirdetail, dirblock))
896
self.assertTrue(found_bzrdir)
897
self.assertEqual(expected_dirblocks,
898
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
899
# you can search a subdir only, with a supplied prefix.
901
for dirblock in osutils.walkdirs('./1dir', '1dir'):
902
result.append(dirblock)
903
self.assertEqual(expected_dirblocks[1:],
904
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
906
def _filter_out_stat(self, result):
907
"""Filter out the stat value from the walkdirs result"""
908
for dirdetail, dirblock in result:
910
for info in dirblock:
911
# Ignore info[3] which is the stat
912
new_dirblock.append((info[0], info[1], info[2], info[4]))
913
dirblock[:] = new_dirblock
915
def _save_platform_info(self):
916
cur_winver = win32utils.winver
917
cur_fs_enc = osutils._fs_enc
918
cur_dir_reader = osutils._selected_dir_reader
920
win32utils.winver = cur_winver
921
osutils._fs_enc = cur_fs_enc
922
osutils._selected_dir_reader = cur_dir_reader
923
self.addCleanup(restore)
925
def assertReadFSDirIs(self, expected):
926
"""Assert the right implementation for _walkdirs_utf8 is chosen."""
927
# Force it to redetect
928
osutils._selected_dir_reader = None
929
# Nothing to list, but should still trigger the selection logic
930
self.assertEqual([(('', '.'), [])], list(osutils._walkdirs_utf8('.')))
931
self.assertIsInstance(osutils._selected_dir_reader, expected)
933
def test_force_walkdirs_utf8_fs_utf8(self):
934
self._save_platform_info()
935
win32utils.winver = None # Avoid the win32 detection code
936
osutils._fs_enc = 'UTF-8'
937
self.assertReadFSDirIs(osutils.UTF8DirReader)
939
def test_force_walkdirs_utf8_fs_ascii(self):
940
self._save_platform_info()
941
win32utils.winver = None # Avoid the win32 detection code
942
osutils._fs_enc = 'US-ASCII'
943
self.assertReadFSDirIs(osutils.UTF8DirReader)
945
def test_force_walkdirs_utf8_fs_ANSI(self):
946
self._save_platform_info()
947
win32utils.winver = None # Avoid the win32 detection code
948
osutils._fs_enc = 'ANSI_X3.4-1968'
949
self.assertReadFSDirIs(osutils.UTF8DirReader)
951
def test_force_walkdirs_utf8_fs_latin1(self):
952
self._save_platform_info()
953
win32utils.winver = None # Avoid the win32 detection code
954
osutils._fs_enc = 'latin1'
955
self.assertReadFSDirIs(osutils.UnicodeDirReader)
957
def test_force_walkdirs_utf8_nt(self):
958
# Disabled because the thunk of the whole walkdirs api is disabled.
959
self.requireFeature(Win32ReadDirFeature)
960
self._save_platform_info()
961
win32utils.winver = 'Windows NT'
962
from bzrlib._walkdirs_win32 import Win32ReadDir
963
self.assertReadFSDirIs(Win32ReadDir)
965
def test_force_walkdirs_utf8_98(self):
966
self.requireFeature(Win32ReadDirFeature)
967
self._save_platform_info()
968
win32utils.winver = 'Windows 98'
969
self.assertReadFSDirIs(osutils.UnicodeDirReader)
971
def test_unicode_walkdirs(self):
972
"""Walkdirs should always return unicode paths."""
973
name0 = u'0file-\xb6'
974
name1 = u'1dir-\u062c\u0648'
975
name2 = u'2file-\u0633'
980
name1 + '/' + name1 + '/',
984
self.build_tree(tree)
986
raise TestSkipped('Could not represent Unicode chars'
987
' in current encoding.')
988
expected_dirblocks = [
990
[(name0, name0, 'file', './' + name0),
991
(name1, name1, 'directory', './' + name1),
992
(name2, name2, 'file', './' + name2),
995
((name1, './' + name1),
996
[(name1 + '/' + name0, name0, 'file', './' + name1
998
(name1 + '/' + name1, name1, 'directory', './' + name1
1002
((name1 + '/' + name1, './' + name1 + '/' + name1),
1007
result = list(osutils.walkdirs('.'))
1008
self._filter_out_stat(result)
1009
self.assertEqual(expected_dirblocks, result)
1010
result = list(osutils.walkdirs(u'./'+name1, name1))
1011
self._filter_out_stat(result)
1012
self.assertEqual(expected_dirblocks[1:], result)
1014
def test_unicode__walkdirs_utf8(self):
1015
"""Walkdirs_utf8 should always return utf8 paths.
1017
The abspath portion might be in unicode or utf-8
1019
name0 = u'0file-\xb6'
1020
name1 = u'1dir-\u062c\u0648'
1021
name2 = u'2file-\u0633'
1025
name1 + '/' + name0,
1026
name1 + '/' + name1 + '/',
1030
self.build_tree(tree)
1031
except UnicodeError:
1032
raise TestSkipped('Could not represent Unicode chars'
1033
' in current encoding.')
1034
name0 = name0.encode('utf8')
1035
name1 = name1.encode('utf8')
1036
name2 = name2.encode('utf8')
1038
expected_dirblocks = [
1040
[(name0, name0, 'file', './' + name0),
1041
(name1, name1, 'directory', './' + name1),
1042
(name2, name2, 'file', './' + name2),
1045
((name1, './' + name1),
1046
[(name1 + '/' + name0, name0, 'file', './' + name1
1048
(name1 + '/' + name1, name1, 'directory', './' + name1
1052
((name1 + '/' + name1, './' + name1 + '/' + name1),
1058
# For ease in testing, if walkdirs_utf8 returns Unicode, assert that
1059
# all abspaths are Unicode, and encode them back into utf8.
1060
for dirdetail, dirblock in osutils._walkdirs_utf8('.'):
1061
self.assertIsInstance(dirdetail[0], str)
1062
if isinstance(dirdetail[1], unicode):
1063
dirdetail = (dirdetail[0], dirdetail[1].encode('utf8'))
1064
dirblock = [list(info) for info in dirblock]
1065
for info in dirblock:
1066
self.assertIsInstance(info[4], unicode)
1067
info[4] = info[4].encode('utf8')
1069
for info in dirblock:
1070
self.assertIsInstance(info[0], str)
1071
self.assertIsInstance(info[1], str)
1072
self.assertIsInstance(info[4], str)
1073
# Remove the stat information
1074
new_dirblock.append((info[0], info[1], info[2], info[4]))
1075
result.append((dirdetail, new_dirblock))
1076
self.assertEqual(expected_dirblocks, result)
1078
def test__walkdirs_utf8_with_unicode_fs(self):
1079
"""UnicodeDirReader should be a safe fallback everywhere
1081
The abspath portion should be in unicode
1083
# Use the unicode reader. TODO: split into driver-and-driven unit
1085
self._save_platform_info()
1086
osutils._selected_dir_reader = osutils.UnicodeDirReader()
1087
name0u = u'0file-\xb6'
1088
name1u = u'1dir-\u062c\u0648'
1089
name2u = u'2file-\u0633'
1093
name1u + '/' + name0u,
1094
name1u + '/' + name1u + '/',
1098
self.build_tree(tree)
1099
except UnicodeError:
1100
raise TestSkipped('Could not represent Unicode chars'
1101
' in current encoding.')
1102
name0 = name0u.encode('utf8')
1103
name1 = name1u.encode('utf8')
1104
name2 = name2u.encode('utf8')
1106
# All of the abspaths should be in unicode, all of the relative paths
1108
expected_dirblocks = [
1110
[(name0, name0, 'file', './' + name0u),
1111
(name1, name1, 'directory', './' + name1u),
1112
(name2, name2, 'file', './' + name2u),
1115
((name1, './' + name1u),
1116
[(name1 + '/' + name0, name0, 'file', './' + name1u
1118
(name1 + '/' + name1, name1, 'directory', './' + name1u
1122
((name1 + '/' + name1, './' + name1u + '/' + name1u),
1127
result = list(osutils._walkdirs_utf8('.'))
1128
self._filter_out_stat(result)
1129
self.assertEqual(expected_dirblocks, result)
1131
def test__walkdirs_utf_win32_find_file(self):
1132
self.requireFeature(Win32ReadDirFeature)
1133
self.requireFeature(tests.UnicodeFilenameFeature)
1134
from bzrlib._walkdirs_win32 import Win32ReadDir
1135
self._save_platform_info()
1136
osutils._selected_dir_reader = osutils.Win32ReadDir()
1137
name0u = u'0file-\xb6'
1138
name1u = u'1dir-\u062c\u0648'
1139
name2u = u'2file-\u0633'
1143
name1u + '/' + name0u,
1144
name1u + '/' + name1u + '/',
1147
self.build_tree(tree)
1148
name0 = name0u.encode('utf8')
1149
name1 = name1u.encode('utf8')
1150
name2 = name2u.encode('utf8')
1152
# All of the abspaths should be in unicode, all of the relative paths
1154
expected_dirblocks = [
1156
[(name0, name0, 'file', './' + name0u),
1157
(name1, name1, 'directory', './' + name1u),
1158
(name2, name2, 'file', './' + name2u),
1161
((name1, './' + name1u),
1162
[(name1 + '/' + name0, name0, 'file', './' + name1u
1164
(name1 + '/' + name1, name1, 'directory', './' + name1u
1168
((name1 + '/' + name1, './' + name1u + '/' + name1u),
1173
result = list(_walkdirs_utf8(u'.'))
1174
self._filter_out_stat(result)
1175
self.assertEqual(expected_dirblocks, result)
1177
def assertStatIsCorrect(self, path, win32stat):
1178
os_stat = os.stat(path)
1179
self.assertEqual(os_stat.st_size, win32stat.st_size)
1180
self.assertAlmostEqual(os_stat.st_mtime, win32stat.st_mtime, places=4)
1181
self.assertAlmostEqual(os_stat.st_ctime, win32stat.st_ctime, places=4)
1182
self.assertAlmostEqual(os_stat.st_atime, win32stat.st_atime, places=4)
1183
self.assertEqual(os_stat.st_dev, win32stat.st_dev)
1184
self.assertEqual(os_stat.st_ino, win32stat.st_ino)
1185
self.assertEqual(os_stat.st_mode, win32stat.st_mode)
1187
def test__walkdirs_utf_win32_find_file_stat_file(self):
1188
"""make sure our Stat values are valid"""
1189
self.requireFeature(Win32ReadDirFeature)
1190
self.requireFeature(tests.UnicodeFilenameFeature)
1191
from bzrlib._walkdirs_win32 import Win32ReadDir
1192
name0u = u'0file-\xb6'
1193
name0 = name0u.encode('utf8')
1194
self.build_tree([name0u])
1195
# I hate to sleep() here, but I'm trying to make the ctime different
1198
f = open(name0u, 'ab')
1200
f.write('just a small update')
1204
result = Win32ReadDir().read_dir('', u'.')
1206
self.assertEqual((name0, name0, 'file'), entry[:3])
1207
self.assertEqual(u'./' + name0u, entry[4])
1208
self.assertStatIsCorrect(entry[4], entry[3])
1209
self.assertNotEqual(entry[3].st_mtime, entry[3].st_ctime)
1211
def test__walkdirs_utf_win32_find_file_stat_directory(self):
1212
"""make sure our Stat values are valid"""
1213
self.requireFeature(Win32ReadDirFeature)
1214
self.requireFeature(tests.UnicodeFilenameFeature)
1215
from bzrlib._walkdirs_win32 import Win32ReadDir
1216
name0u = u'0dir-\u062c\u0648'
1217
name0 = name0u.encode('utf8')
1218
self.build_tree([name0u + '/'])
1220
result = Win32ReadDir().read_dir('', u'.')
1222
self.assertEqual((name0, name0, 'directory'), entry[:3])
1223
self.assertEqual(u'./' + name0u, entry[4])
1224
self.assertStatIsCorrect(entry[4], entry[3])
1226
def assertPathCompare(self, path_less, path_greater):
1227
"""check that path_less and path_greater compare correctly."""
1228
self.assertEqual(0, osutils.compare_paths_prefix_order(
1229
path_less, path_less))
1230
self.assertEqual(0, osutils.compare_paths_prefix_order(
1231
path_greater, path_greater))
1232
self.assertEqual(-1, osutils.compare_paths_prefix_order(
1233
path_less, path_greater))
1234
self.assertEqual(1, osutils.compare_paths_prefix_order(
1235
path_greater, path_less))
1237
def test_compare_paths_prefix_order(self):
1238
# root before all else
1239
self.assertPathCompare("/", "/a")
1240
# alpha within a dir
1241
self.assertPathCompare("/a", "/b")
1242
self.assertPathCompare("/b", "/z")
1243
# high dirs before lower.
1244
self.assertPathCompare("/z", "/a/a")
1245
# except if the deeper dir should be output first
1246
self.assertPathCompare("/a/b/c", "/d/g")
1247
# lexical betwen dirs of the same height
1248
self.assertPathCompare("/a/z", "/z/z")
1249
self.assertPathCompare("/a/c/z", "/a/d/e")
1251
# this should also be consistent for no leading / paths
1252
# root before all else
1253
self.assertPathCompare("", "a")
1254
# alpha within a dir
1255
self.assertPathCompare("a", "b")
1256
self.assertPathCompare("b", "z")
1257
# high dirs before lower.
1258
self.assertPathCompare("z", "a/a")
1259
# except if the deeper dir should be output first
1260
self.assertPathCompare("a/b/c", "d/g")
1261
# lexical betwen dirs of the same height
1262
self.assertPathCompare("a/z", "z/z")
1263
self.assertPathCompare("a/c/z", "a/d/e")
1265
def test_path_prefix_sorting(self):
1266
"""Doing a sort on path prefix should match our sample data."""
1281
dir_sorted_paths = [
1297
sorted(original_paths, key=osutils.path_prefix_key))
1298
# using the comparison routine shoudl work too:
1301
sorted(original_paths, cmp=osutils.compare_paths_prefix_order))
1304
class TestCopyTree(TestCaseInTempDir):
1306
def test_copy_basic_tree(self):
1307
self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c'])
1308
osutils.copy_tree('source', 'target')
1309
self.assertEqual(['a', 'b'], sorted(os.listdir('target')))
1310
self.assertEqual(['c'], os.listdir('target/b'))
1312
def test_copy_tree_target_exists(self):
1313
self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c',
1315
osutils.copy_tree('source', 'target')
1316
self.assertEqual(['a', 'b'], sorted(os.listdir('target')))
1317
self.assertEqual(['c'], os.listdir('target/b'))
1319
def test_copy_tree_symlinks(self):
1320
self.requireFeature(SymlinkFeature)
1321
self.build_tree(['source/'])
1322
os.symlink('a/generic/path', 'source/lnk')
1323
osutils.copy_tree('source', 'target')
1324
self.assertEqual(['lnk'], os.listdir('target'))
1325
self.assertEqual('a/generic/path', os.readlink('target/lnk'))
1327
def test_copy_tree_handlers(self):
1328
processed_files = []
1329
processed_links = []
1330
def file_handler(from_path, to_path):
1331
processed_files.append(('f', from_path, to_path))
1332
def dir_handler(from_path, to_path):
1333
processed_files.append(('d', from_path, to_path))
1334
def link_handler(from_path, to_path):
1335
processed_links.append((from_path, to_path))
1336
handlers = {'file':file_handler,
1337
'directory':dir_handler,
1338
'symlink':link_handler,
1341
self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c'])
1342
if osutils.has_symlinks():
1343
os.symlink('a/generic/path', 'source/lnk')
1344
osutils.copy_tree('source', 'target', handlers=handlers)
1346
self.assertEqual([('d', 'source', 'target'),
1347
('f', 'source/a', 'target/a'),
1348
('d', 'source/b', 'target/b'),
1349
('f', 'source/b/c', 'target/b/c'),
1351
self.failIfExists('target')
1352
if osutils.has_symlinks():
1353
self.assertEqual([('source/lnk', 'target/lnk')], processed_links)
1356
#class TestTerminalEncoding has been moved to test_osutils_encodings.py
1357
# [bialix] 2006/12/26
1360
class TestSetUnsetEnv(TestCase):
1361
"""Test updating the environment"""
1364
super(TestSetUnsetEnv, self).setUp()
1366
self.assertEqual(None, os.environ.get('BZR_TEST_ENV_VAR'),
1367
'Environment was not cleaned up properly.'
1368
' Variable BZR_TEST_ENV_VAR should not exist.')
1370
if 'BZR_TEST_ENV_VAR' in os.environ:
1371
del os.environ['BZR_TEST_ENV_VAR']
1373
self.addCleanup(cleanup)
1376
"""Test that we can set an env variable"""
1377
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
1378
self.assertEqual(None, old)
1379
self.assertEqual('foo', os.environ.get('BZR_TEST_ENV_VAR'))
1381
def test_double_set(self):
1382
"""Test that we get the old value out"""
1383
osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
1384
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'bar')
1385
self.assertEqual('foo', old)
1386
self.assertEqual('bar', os.environ.get('BZR_TEST_ENV_VAR'))
1388
def test_unicode(self):
1389
"""Environment can only contain plain strings
1391
So Unicode strings must be encoded.
1393
uni_val, env_val = probe_unicode_in_user_encoding()
1395
raise TestSkipped('Cannot find a unicode character that works in'
1396
' encoding %s' % (bzrlib.user_encoding,))
1398
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', uni_val)
1399
self.assertEqual(env_val, os.environ.get('BZR_TEST_ENV_VAR'))
1401
def test_unset(self):
1402
"""Test that passing None will remove the env var"""
1403
osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
1404
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', None)
1405
self.assertEqual('foo', old)
1406
self.assertEqual(None, os.environ.get('BZR_TEST_ENV_VAR'))
1407
self.failIf('BZR_TEST_ENV_VAR' in os.environ)
1410
class TestLocalTimeOffset(TestCase):
1412
def test_local_time_offset(self):
1413
"""Test that local_time_offset() returns a sane value."""
1414
offset = osutils.local_time_offset()
1415
self.assertTrue(isinstance(offset, int))
1416
# Test that the offset is no more than a eighteen hours in
1418
# Time zone handling is system specific, so it is difficult to
1419
# do more specific tests, but a value outside of this range is
1421
eighteen_hours = 18 * 3600
1422
self.assertTrue(-eighteen_hours < offset < eighteen_hours)
1424
def test_local_time_offset_with_timestamp(self):
1425
"""Test that local_time_offset() works with a timestamp."""
1426
offset = osutils.local_time_offset(1000000000.1234567)
1427
self.assertTrue(isinstance(offset, int))
1428
eighteen_hours = 18 * 3600
1429
self.assertTrue(-eighteen_hours < offset < eighteen_hours)
1432
class TestShaFileByName(TestCaseInTempDir):
1434
def test_sha_empty(self):
1435
self.build_tree_contents([('foo', '')])
1436
expected_sha = osutils.sha_string('')
1437
self.assertEqual(expected_sha, osutils.sha_file_by_name('foo'))
1439
def test_sha_mixed_endings(self):
1440
text = 'test\r\nwith\nall\rpossible line endings\r\n'
1441
self.build_tree_contents([('foo', text)])
1442
expected_sha = osutils.sha_string(text)
1443
self.assertEqual(expected_sha, osutils.sha_file_by_name('foo'))
1447
r'''# Copyright (C) 2005, 2006 Canonical Ltd
1449
# This program is free software; you can redistribute it and/or modify
1450
# it under the terms of the GNU General Public License as published by
1451
# the Free Software Foundation; either version 2 of the License, or
1452
# (at your option) any later version.
1454
# This program is distributed in the hope that it will be useful,
1455
# but WITHOUT ANY WARRANTY; without even the implied warranty of
1456
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1457
# GNU General Public License for more details.
1459
# You should have received a copy of the GNU General Public License
1460
# along with this program; if not, write to the Free Software
1461
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1464
# NOTE: If update these, please also update the help for global-options in
1465
# bzrlib/help_topics/__init__.py
1468
"""Set of flags that enable different debug behaviour.
1470
These are set with eg ``-Dlock`` on the bzr command line.
1474
* auth - show authentication sections used
1475
* error - show stack traces for all top level exceptions
1476
* evil - capture call sites that do expensive or badly-scaling operations.
1477
* fetch - trace history copying between repositories
1478
* graph - trace graph traversal information
1479
* hashcache - log every time a working file is read to determine its hash
1480
* hooks - trace hook execution
1481
* hpss - trace smart protocol requests and responses
1482
* http - trace http connections, requests and responses
1483
* index - trace major index operations
1484
* knit - trace knit operations
1485
* lock - trace when lockdir locks are taken or released
1486
* merge - emit information for debugging merges
1487
* pack - emit information about pack operations
1493
class TestResourceLoading(TestCaseInTempDir):
1495
def test_resource_string(self):
1496
# test resource in bzrlib
1497
text = osutils.resource_string('bzrlib', 'debug.py')
1498
self.assertEquals(_debug_text, text)
1499
# test resource under bzrlib
1500
text = osutils.resource_string('bzrlib.ui', 'text.py')
1501
self.assertContainsRe(text, "class TextUIFactory")
1502
# test unsupported package
1503
self.assertRaises(errors.BzrError, osutils.resource_string, 'zzzz',
1505
# test unknown resource
1506
self.assertRaises(IOError, osutils.resource_string, 'bzrlib', 'yyy.xx')