1
# Copyright (C) 2005, 2006, 2007, 2008 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
33
from bzrlib.errors import BzrBadParameterNotUnicode, InvalidURL
34
from bzrlib.osutils import (
36
is_inside_or_parent_of_any,
41
from bzrlib.tests import (
44
probe_unicode_in_user_encoding,
53
from bzrlib.tests.file_utils import (
56
from bzrlib.tests.test__walkdirs_win32 import Win32ReadDirFeature
59
class _UTF8DirReaderFeature(Feature):
63
from bzrlib import _readdir_pyx
64
self.reader = _readdir_pyx.UTF8DirReader
69
def feature_name(self):
70
return 'bzrlib._readdir_pyx'
72
UTF8DirReaderFeature = _UTF8DirReaderFeature()
75
class TestOSUtils(TestCaseInTempDir):
77
def test_contains_whitespace(self):
78
self.failUnless(osutils.contains_whitespace(u' '))
79
self.failUnless(osutils.contains_whitespace(u'hello there'))
80
self.failUnless(osutils.contains_whitespace(u'hellothere\n'))
81
self.failUnless(osutils.contains_whitespace(u'hello\nthere'))
82
self.failUnless(osutils.contains_whitespace(u'hello\rthere'))
83
self.failUnless(osutils.contains_whitespace(u'hello\tthere'))
85
# \xa0 is "Non-breaking-space" which on some python locales thinks it
86
# is whitespace, but we do not.
87
self.failIf(osutils.contains_whitespace(u''))
88
self.failIf(osutils.contains_whitespace(u'hellothere'))
89
self.failIf(osutils.contains_whitespace(u'hello\xa0there'))
91
def test_fancy_rename(self):
92
# This should work everywhere
94
osutils.fancy_rename(a, b,
95
rename_func=os.rename,
96
unlink_func=os.unlink)
98
open('a', 'wb').write('something in a\n')
100
self.failIfExists('a')
101
self.failUnlessExists('b')
102
self.check_file_contents('b', 'something in a\n')
104
open('a', 'wb').write('new something in a\n')
107
self.check_file_contents('a', 'something in a\n')
109
def test_rename(self):
110
# Rename should be semi-atomic on all platforms
111
open('a', 'wb').write('something in a\n')
112
osutils.rename('a', 'b')
113
self.failIfExists('a')
114
self.failUnlessExists('b')
115
self.check_file_contents('b', 'something in a\n')
117
open('a', 'wb').write('new something in a\n')
118
osutils.rename('b', 'a')
120
self.check_file_contents('a', 'something in a\n')
122
# TODO: test fancy_rename using a MemoryTransport
124
def test_rename_change_case(self):
125
# on Windows we should be able to change filename case by rename
126
self.build_tree(['a', 'b/'])
127
osutils.rename('a', 'A')
128
osutils.rename('b', 'B')
129
# we can't use failUnlessExists on case-insensitive filesystem
130
# so try to check shape of the tree
131
shape = sorted(os.listdir('.'))
132
self.assertEquals(['A', 'B'], shape)
134
def test_01_rand_chars_empty(self):
135
result = osutils.rand_chars(0)
136
self.assertEqual(result, '')
138
def test_02_rand_chars_100(self):
139
result = osutils.rand_chars(100)
140
self.assertEqual(len(result), 100)
141
self.assertEqual(type(result), str)
142
self.assertContainsRe(result, r'^[a-z0-9]{100}$')
144
def test_is_inside(self):
145
is_inside = osutils.is_inside
146
self.assertTrue(is_inside('src', 'src/foo.c'))
147
self.assertFalse(is_inside('src', 'srccontrol'))
148
self.assertTrue(is_inside('src', 'src/a/a/a/foo.c'))
149
self.assertTrue(is_inside('foo.c', 'foo.c'))
150
self.assertFalse(is_inside('foo.c', ''))
151
self.assertTrue(is_inside('', 'foo.c'))
153
def test_is_inside_any(self):
154
SRC_FOO_C = pathjoin('src', 'foo.c')
155
for dirs, fn in [(['src', 'doc'], SRC_FOO_C),
156
(['src'], SRC_FOO_C),
159
self.assert_(is_inside_any(dirs, fn))
160
for dirs, fn in [(['src'], 'srccontrol'),
161
(['src'], 'srccontrol/foo')]:
162
self.assertFalse(is_inside_any(dirs, fn))
164
def test_is_inside_or_parent_of_any(self):
165
for dirs, fn in [(['src', 'doc'], 'src/foo.c'),
166
(['src'], 'src/foo.c'),
167
(['src/bar.c'], 'src'),
168
(['src/bar.c', 'bla/foo.c'], 'src'),
171
self.assert_(is_inside_or_parent_of_any(dirs, fn))
173
for dirs, fn in [(['src'], 'srccontrol'),
174
(['srccontrol/foo.c'], 'src'),
175
(['src'], 'srccontrol/foo')]:
176
self.assertFalse(is_inside_or_parent_of_any(dirs, fn))
178
def test_rmtree(self):
179
# Check to remove tree with read-only files/dirs
181
f = file('dir/file', 'w')
184
# would like to also try making the directory readonly, but at the
185
# moment python shutil.rmtree doesn't handle that properly - it would
186
# need to chmod the directory before removing things inside it - deferred
187
# for now -- mbp 20060505
188
# osutils.make_readonly('dir')
189
osutils.make_readonly('dir/file')
191
osutils.rmtree('dir')
193
self.failIfExists('dir/file')
194
self.failIfExists('dir')
196
def test_file_kind(self):
197
self.build_tree(['file', 'dir/'])
198
self.assertEquals('file', osutils.file_kind('file'))
199
self.assertEquals('directory', osutils.file_kind('dir/'))
200
if osutils.has_symlinks():
201
os.symlink('symlink', 'symlink')
202
self.assertEquals('symlink', osutils.file_kind('symlink'))
204
# TODO: jam 20060529 Test a block device
206
os.lstat('/dev/null')
208
if e.errno not in (errno.ENOENT,):
211
self.assertEquals('chardev', osutils.file_kind('/dev/null'))
213
mkfifo = getattr(os, 'mkfifo', None)
217
self.assertEquals('fifo', osutils.file_kind('fifo'))
221
AF_UNIX = getattr(socket, 'AF_UNIX', None)
223
s = socket.socket(AF_UNIX)
226
self.assertEquals('socket', osutils.file_kind('socket'))
230
def test_kind_marker(self):
231
self.assertEqual(osutils.kind_marker('file'), '')
232
self.assertEqual(osutils.kind_marker('directory'), '/')
233
self.assertEqual(osutils.kind_marker('symlink'), '@')
234
self.assertEqual(osutils.kind_marker('tree-reference'), '+')
236
def test_get_umask(self):
237
if sys.platform == 'win32':
238
# umask always returns '0', no way to set it
239
self.assertEqual(0, osutils.get_umask())
242
orig_umask = osutils.get_umask()
245
self.assertEqual(0222, osutils.get_umask())
247
self.assertEqual(0022, osutils.get_umask())
249
self.assertEqual(0002, osutils.get_umask())
251
self.assertEqual(0027, osutils.get_umask())
255
def assertFormatedDelta(self, expected, seconds):
256
"""Assert osutils.format_delta formats as expected"""
257
actual = osutils.format_delta(seconds)
258
self.assertEqual(expected, actual)
260
def test_format_delta(self):
261
self.assertFormatedDelta('0 seconds ago', 0)
262
self.assertFormatedDelta('1 second ago', 1)
263
self.assertFormatedDelta('10 seconds ago', 10)
264
self.assertFormatedDelta('59 seconds ago', 59)
265
self.assertFormatedDelta('89 seconds ago', 89)
266
self.assertFormatedDelta('1 minute, 30 seconds ago', 90)
267
self.assertFormatedDelta('3 minutes, 0 seconds ago', 180)
268
self.assertFormatedDelta('3 minutes, 1 second ago', 181)
269
self.assertFormatedDelta('10 minutes, 15 seconds ago', 615)
270
self.assertFormatedDelta('30 minutes, 59 seconds ago', 1859)
271
self.assertFormatedDelta('31 minutes, 0 seconds ago', 1860)
272
self.assertFormatedDelta('60 minutes, 0 seconds ago', 3600)
273
self.assertFormatedDelta('89 minutes, 59 seconds ago', 5399)
274
self.assertFormatedDelta('1 hour, 30 minutes ago', 5400)
275
self.assertFormatedDelta('2 hours, 30 minutes ago', 9017)
276
self.assertFormatedDelta('10 hours, 0 minutes ago', 36000)
277
self.assertFormatedDelta('24 hours, 0 minutes ago', 86400)
278
self.assertFormatedDelta('35 hours, 59 minutes ago', 129599)
279
self.assertFormatedDelta('36 hours, 0 minutes ago', 129600)
280
self.assertFormatedDelta('36 hours, 0 minutes ago', 129601)
281
self.assertFormatedDelta('36 hours, 1 minute ago', 129660)
282
self.assertFormatedDelta('36 hours, 1 minute ago', 129661)
283
self.assertFormatedDelta('84 hours, 10 minutes ago', 303002)
285
# We handle when time steps the wrong direction because computers
286
# don't have synchronized clocks.
287
self.assertFormatedDelta('84 hours, 10 minutes in the future', -303002)
288
self.assertFormatedDelta('1 second in the future', -1)
289
self.assertFormatedDelta('2 seconds in the future', -2)
291
def test_format_date(self):
292
self.assertRaises(errors.UnsupportedTimezoneFormat,
293
osutils.format_date, 0, timezone='foo')
294
self.assertIsInstance(osutils.format_date(0), str)
295
self.assertIsInstance(osutils.format_local_date(0), unicode)
296
# Testing for the actual value of the local weekday without
297
# duplicating the code from format_date is difficult.
298
# Instead blackbox.test_locale should check for localized
299
# dates once they do occur in output strings.
301
def test_dereference_path(self):
302
self.requireFeature(SymlinkFeature)
303
cwd = osutils.realpath('.')
305
bar_path = osutils.pathjoin(cwd, 'bar')
306
# Using './' to avoid bug #1213894 (first path component not
307
# dereferenced) in Python 2.4.1 and earlier
308
self.assertEqual(bar_path, osutils.realpath('./bar'))
309
os.symlink('bar', 'foo')
310
self.assertEqual(bar_path, osutils.realpath('./foo'))
312
# Does not dereference terminal symlinks
313
foo_path = osutils.pathjoin(cwd, 'foo')
314
self.assertEqual(foo_path, osutils.dereference_path('./foo'))
316
# Dereferences parent symlinks
318
baz_path = osutils.pathjoin(bar_path, 'baz')
319
self.assertEqual(baz_path, osutils.dereference_path('./foo/baz'))
321
# Dereferences parent symlinks that are the first path element
322
self.assertEqual(baz_path, osutils.dereference_path('foo/baz'))
324
# Dereferences parent symlinks in absolute paths
325
foo_baz_path = osutils.pathjoin(foo_path, 'baz')
326
self.assertEqual(baz_path, osutils.dereference_path(foo_baz_path))
328
def test_changing_access(self):
329
f = file('file', 'w')
333
# Make a file readonly
334
osutils.make_readonly('file')
335
mode = os.lstat('file').st_mode
336
self.assertEqual(mode, mode & 0777555)
338
# Make a file writable
339
osutils.make_writable('file')
340
mode = os.lstat('file').st_mode
341
self.assertEqual(mode, mode | 0200)
343
if osutils.has_symlinks():
344
# should not error when handed a symlink
345
os.symlink('nonexistent', 'dangling')
346
osutils.make_readonly('dangling')
347
osutils.make_writable('dangling')
349
def test_kind_marker(self):
350
self.assertEqual("", osutils.kind_marker("file"))
351
self.assertEqual("/", osutils.kind_marker(osutils._directory_kind))
352
self.assertEqual("@", osutils.kind_marker("symlink"))
353
self.assertRaises(errors.BzrError, osutils.kind_marker, "unknown")
355
def test_host_os_dereferences_symlinks(self):
356
osutils.host_os_dereferences_symlinks()
359
class TestPumpFile(TestCase):
360
"""Test pumpfile method."""
362
# create a test datablock
363
self.block_size = 512
364
pattern = '0123456789ABCDEF'
365
self.test_data = pattern * (3 * self.block_size / len(pattern))
366
self.test_data_len = len(self.test_data)
368
def test_bracket_block_size(self):
369
"""Read data in blocks with the requested read size bracketing the
371
# make sure test data is larger than max read size
372
self.assertTrue(self.test_data_len > self.block_size)
374
from_file = FakeReadFile(self.test_data)
377
# read (max / 2) bytes and verify read size wasn't affected
378
num_bytes_to_read = self.block_size / 2
379
pumpfile(from_file, to_file, num_bytes_to_read, self.block_size)
380
self.assertEqual(from_file.get_max_read_size(), num_bytes_to_read)
381
self.assertEqual(from_file.get_read_count(), 1)
383
# read (max) bytes and verify read size wasn't affected
384
num_bytes_to_read = self.block_size
385
from_file.reset_read_count()
386
pumpfile(from_file, to_file, num_bytes_to_read, self.block_size)
387
self.assertEqual(from_file.get_max_read_size(), num_bytes_to_read)
388
self.assertEqual(from_file.get_read_count(), 1)
390
# read (max + 1) bytes and verify read size was limited
391
num_bytes_to_read = self.block_size + 1
392
from_file.reset_read_count()
393
pumpfile(from_file, to_file, num_bytes_to_read, self.block_size)
394
self.assertEqual(from_file.get_max_read_size(), self.block_size)
395
self.assertEqual(from_file.get_read_count(), 2)
397
# finish reading the rest of the data
398
num_bytes_to_read = self.test_data_len - to_file.tell()
399
pumpfile(from_file, to_file, num_bytes_to_read, self.block_size)
401
# report error if the data wasn't equal (we only report the size due
402
# to the length of the data)
403
response_data = to_file.getvalue()
404
if response_data != self.test_data:
405
message = "Data not equal. Expected %d bytes, received %d."
406
self.fail(message % (len(response_data), self.test_data_len))
408
def test_specified_size(self):
409
"""Request a transfer larger than the maximum block size and verify
410
that the maximum read doesn't exceed the block_size."""
411
# make sure test data is larger than max read size
412
self.assertTrue(self.test_data_len > self.block_size)
414
# retrieve data in blocks
415
from_file = FakeReadFile(self.test_data)
417
pumpfile(from_file, to_file, self.test_data_len, self.block_size)
419
# verify read size was equal to the maximum read size
420
self.assertTrue(from_file.get_max_read_size() > 0)
421
self.assertEqual(from_file.get_max_read_size(), self.block_size)
422
self.assertEqual(from_file.get_read_count(), 3)
424
# report error if the data wasn't equal (we only report the size due
425
# to the length of the data)
426
response_data = to_file.getvalue()
427
if response_data != self.test_data:
428
message = "Data not equal. Expected %d bytes, received %d."
429
self.fail(message % (len(response_data), self.test_data_len))
431
def test_to_eof(self):
432
"""Read to end-of-file and verify that the reads are not larger than
433
the maximum read size."""
434
# make sure test data is larger than max read size
435
self.assertTrue(self.test_data_len > self.block_size)
437
# retrieve data to EOF
438
from_file = FakeReadFile(self.test_data)
440
pumpfile(from_file, to_file, -1, self.block_size)
442
# verify read size was equal to the maximum read size
443
self.assertEqual(from_file.get_max_read_size(), self.block_size)
444
self.assertEqual(from_file.get_read_count(), 4)
446
# report error if the data wasn't equal (we only report the size due
447
# to the length of the data)
448
response_data = to_file.getvalue()
449
if response_data != self.test_data:
450
message = "Data not equal. Expected %d bytes, received %d."
451
self.fail(message % (len(response_data), self.test_data_len))
453
def test_defaults(self):
454
"""Verifies that the default arguments will read to EOF -- this
455
test verifies that any existing usages of pumpfile will not be broken
456
with this new version."""
457
# retrieve data using default (old) pumpfile method
458
from_file = FakeReadFile(self.test_data)
460
pumpfile(from_file, to_file)
462
# report error if the data wasn't equal (we only report the size due
463
# to the length of the data)
464
response_data = to_file.getvalue()
465
if response_data != self.test_data:
466
message = "Data not equal. Expected %d bytes, received %d."
467
self.fail(message % (len(response_data), self.test_data_len))
470
class TestPumpStringFile(TestCase):
472
def test_empty(self):
474
pump_string_file("", output)
475
self.assertEqual("", output.getvalue())
477
def test_more_than_segment_size(self):
479
pump_string_file("123456789", output, 2)
480
self.assertEqual("123456789", output.getvalue())
482
def test_segment_size(self):
484
pump_string_file("12", output, 2)
485
self.assertEqual("12", output.getvalue())
487
def test_segment_size_multiple(self):
489
pump_string_file("1234", output, 2)
490
self.assertEqual("1234", output.getvalue())
493
class TestSafeUnicode(TestCase):
495
def test_from_ascii_string(self):
496
self.assertEqual(u'foobar', osutils.safe_unicode('foobar'))
498
def test_from_unicode_string_ascii_contents(self):
499
self.assertEqual(u'bargam', osutils.safe_unicode(u'bargam'))
501
def test_from_unicode_string_unicode_contents(self):
502
self.assertEqual(u'bargam\xae', osutils.safe_unicode(u'bargam\xae'))
504
def test_from_utf8_string(self):
505
self.assertEqual(u'foo\xae', osutils.safe_unicode('foo\xc2\xae'))
507
def test_bad_utf8_string(self):
508
self.assertRaises(BzrBadParameterNotUnicode,
509
osutils.safe_unicode,
513
class TestSafeUtf8(TestCase):
515
def test_from_ascii_string(self):
517
self.assertEqual('foobar', osutils.safe_utf8(f))
519
def test_from_unicode_string_ascii_contents(self):
520
self.assertEqual('bargam', osutils.safe_utf8(u'bargam'))
522
def test_from_unicode_string_unicode_contents(self):
523
self.assertEqual('bargam\xc2\xae', osutils.safe_utf8(u'bargam\xae'))
525
def test_from_utf8_string(self):
526
self.assertEqual('foo\xc2\xae', osutils.safe_utf8('foo\xc2\xae'))
528
def test_bad_utf8_string(self):
529
self.assertRaises(BzrBadParameterNotUnicode,
530
osutils.safe_utf8, '\xbb\xbb')
533
class TestSafeRevisionId(TestCase):
535
def test_from_ascii_string(self):
536
# this shouldn't give a warning because it's getting an ascii string
537
self.assertEqual('foobar', osutils.safe_revision_id('foobar'))
539
def test_from_unicode_string_ascii_contents(self):
540
self.assertEqual('bargam',
541
osutils.safe_revision_id(u'bargam', warn=False))
543
def test_from_unicode_deprecated(self):
544
self.assertEqual('bargam',
545
self.callDeprecated([osutils._revision_id_warning],
546
osutils.safe_revision_id, u'bargam'))
548
def test_from_unicode_string_unicode_contents(self):
549
self.assertEqual('bargam\xc2\xae',
550
osutils.safe_revision_id(u'bargam\xae', warn=False))
552
def test_from_utf8_string(self):
553
self.assertEqual('foo\xc2\xae',
554
osutils.safe_revision_id('foo\xc2\xae'))
557
"""Currently, None is a valid revision_id"""
558
self.assertEqual(None, osutils.safe_revision_id(None))
561
class TestSafeFileId(TestCase):
563
def test_from_ascii_string(self):
564
self.assertEqual('foobar', osutils.safe_file_id('foobar'))
566
def test_from_unicode_string_ascii_contents(self):
567
self.assertEqual('bargam', osutils.safe_file_id(u'bargam', warn=False))
569
def test_from_unicode_deprecated(self):
570
self.assertEqual('bargam',
571
self.callDeprecated([osutils._file_id_warning],
572
osutils.safe_file_id, u'bargam'))
574
def test_from_unicode_string_unicode_contents(self):
575
self.assertEqual('bargam\xc2\xae',
576
osutils.safe_file_id(u'bargam\xae', warn=False))
578
def test_from_utf8_string(self):
579
self.assertEqual('foo\xc2\xae',
580
osutils.safe_file_id('foo\xc2\xae'))
583
"""Currently, None is a valid revision_id"""
584
self.assertEqual(None, osutils.safe_file_id(None))
587
class TestWin32Funcs(TestCase):
588
"""Test that the _win32 versions of os utilities return appropriate paths."""
590
def test_abspath(self):
591
self.assertEqual('C:/foo', osutils._win32_abspath('C:\\foo'))
592
self.assertEqual('C:/foo', osutils._win32_abspath('C:/foo'))
593
self.assertEqual('//HOST/path', osutils._win32_abspath(r'\\HOST\path'))
594
self.assertEqual('//HOST/path', osutils._win32_abspath('//HOST/path'))
596
def test_realpath(self):
597
self.assertEqual('C:/foo', osutils._win32_realpath('C:\\foo'))
598
self.assertEqual('C:/foo', osutils._win32_realpath('C:/foo'))
600
def test_pathjoin(self):
601
self.assertEqual('path/to/foo', osutils._win32_pathjoin('path', 'to', 'foo'))
602
self.assertEqual('C:/foo', osutils._win32_pathjoin('path\\to', 'C:\\foo'))
603
self.assertEqual('C:/foo', osutils._win32_pathjoin('path/to', 'C:/foo'))
604
self.assertEqual('path/to/foo', osutils._win32_pathjoin('path/to/', 'foo'))
605
self.assertEqual('/foo', osutils._win32_pathjoin('C:/path/to/', '/foo'))
606
self.assertEqual('/foo', osutils._win32_pathjoin('C:\\path\\to\\', '\\foo'))
608
def test_normpath(self):
609
self.assertEqual('path/to/foo', osutils._win32_normpath(r'path\\from\..\to\.\foo'))
610
self.assertEqual('path/to/foo', osutils._win32_normpath('path//from/../to/./foo'))
612
def test_getcwd(self):
613
cwd = osutils._win32_getcwd()
614
os_cwd = os.getcwdu()
615
self.assertEqual(os_cwd[1:].replace('\\', '/'), cwd[1:])
616
# win32 is inconsistent whether it returns lower or upper case
617
# and even if it was consistent the user might type the other
618
# so we force it to uppercase
619
# running python.exe under cmd.exe return capital C:\\
620
# running win32 python inside a cygwin shell returns lowercase
621
self.assertEqual(os_cwd[0].upper(), cwd[0])
623
def test_fixdrive(self):
624
self.assertEqual('H:/foo', osutils._win32_fixdrive('h:/foo'))
625
self.assertEqual('H:/foo', osutils._win32_fixdrive('H:/foo'))
626
self.assertEqual('C:\\foo', osutils._win32_fixdrive('c:\\foo'))
628
def test_win98_abspath(self):
630
self.assertEqual('C:/foo', osutils._win98_abspath('C:\\foo'))
631
self.assertEqual('C:/foo', osutils._win98_abspath('C:/foo'))
633
self.assertEqual('//HOST/path', osutils._win98_abspath(r'\\HOST\path'))
634
self.assertEqual('//HOST/path', osutils._win98_abspath('//HOST/path'))
636
cwd = osutils.getcwd().rstrip('/')
637
drive = osutils._nt_splitdrive(cwd)[0]
638
self.assertEqual(cwd+'/path', osutils._win98_abspath('path'))
639
self.assertEqual(drive+'/path', osutils._win98_abspath('/path'))
642
self.assertEqual(cwd+'/'+u, osutils._win98_abspath(u))
645
class TestWin32FuncsDirs(TestCaseInTempDir):
646
"""Test win32 functions that create files."""
648
def test_getcwd(self):
649
if win32utils.winver == 'Windows 98':
650
raise TestSkipped('Windows 98 cannot handle unicode filenames')
651
# Make sure getcwd can handle unicode filenames
655
raise TestSkipped("Unable to create Unicode filename")
658
# TODO: jam 20060427 This will probably fail on Mac OSX because
659
# it will change the normalization of B\xe5gfors
660
# Consider using a different unicode character, or make
661
# osutils.getcwd() renormalize the path.
662
self.assertEndsWith(osutils._win32_getcwd(), u'mu-\xb5')
664
def test_minimum_path_selection(self):
665
self.assertEqual(set(),
666
osutils.minimum_path_selection([]))
667
self.assertEqual(set(['a', 'b']),
668
osutils.minimum_path_selection(['a', 'b']))
669
self.assertEqual(set(['a/', 'b']),
670
osutils.minimum_path_selection(['a/', 'b']))
671
self.assertEqual(set(['a/', 'b']),
672
osutils.minimum_path_selection(['a/c', 'a/', 'b']))
674
def test_mkdtemp(self):
675
tmpdir = osutils._win32_mkdtemp(dir='.')
676
self.assertFalse('\\' in tmpdir)
678
def test_rename(self):
686
osutils._win32_rename('b', 'a')
687
self.failUnlessExists('a')
688
self.failIfExists('b')
689
self.assertFileEqual('baz\n', 'a')
691
def test_rename_missing_file(self):
697
osutils._win32_rename('b', 'a')
698
except (IOError, OSError), e:
699
self.assertEqual(errno.ENOENT, e.errno)
700
self.assertFileEqual('foo\n', 'a')
702
def test_rename_missing_dir(self):
705
osutils._win32_rename('b', 'a')
706
except (IOError, OSError), e:
707
self.assertEqual(errno.ENOENT, e.errno)
709
def test_rename_current_dir(self):
712
# You can't rename the working directory
713
# doing rename non-existant . usually
714
# just raises ENOENT, since non-existant
717
osutils._win32_rename('b', '.')
718
except (IOError, OSError), e:
719
self.assertEqual(errno.ENOENT, e.errno)
721
def test_splitpath(self):
722
def check(expected, path):
723
self.assertEqual(expected, osutils.splitpath(path))
726
check(['a', 'b'], 'a/b')
727
check(['a', 'b'], 'a/./b')
728
check(['a', '.b'], 'a/.b')
729
check(['a', '.b'], 'a\\.b')
731
self.assertRaises(errors.BzrError, osutils.splitpath, 'a/../b')
734
class TestMacFuncsDirs(TestCaseInTempDir):
735
"""Test mac special functions that require directories."""
737
def test_getcwd(self):
738
# On Mac, this will actually create Ba\u030agfors
739
# but chdir will still work, because it accepts both paths
741
os.mkdir(u'B\xe5gfors')
743
raise TestSkipped("Unable to create Unicode filename")
745
os.chdir(u'B\xe5gfors')
746
self.assertEndsWith(osutils._mac_getcwd(), u'B\xe5gfors')
748
def test_getcwd_nonnorm(self):
749
# Test that _mac_getcwd() will normalize this path
751
os.mkdir(u'Ba\u030agfors')
753
raise TestSkipped("Unable to create Unicode filename")
755
os.chdir(u'Ba\u030agfors')
756
self.assertEndsWith(osutils._mac_getcwd(), u'B\xe5gfors')
759
class TestChunksToLines(TestCase):
761
def test_smoketest(self):
762
self.assertEqual(['foo\n', 'bar\n', 'baz\n'],
763
osutils.chunks_to_lines(['foo\nbar', '\nbaz\n']))
764
self.assertEqual(['foo\n', 'bar\n', 'baz\n'],
765
osutils.chunks_to_lines(['foo\n', 'bar\n', 'baz\n']))
767
def test_is_compiled(self):
768
from bzrlib.tests.test__chunks_to_lines import CompiledChunksToLinesFeature
769
if CompiledChunksToLinesFeature:
770
from bzrlib._chunks_to_lines_pyx import chunks_to_lines
772
from bzrlib._chunks_to_lines_py import chunks_to_lines
773
self.assertIs(chunks_to_lines, osutils.chunks_to_lines)
776
class TestSplitLines(TestCase):
778
def test_split_unicode(self):
779
self.assertEqual([u'foo\n', u'bar\xae'],
780
osutils.split_lines(u'foo\nbar\xae'))
781
self.assertEqual([u'foo\n', u'bar\xae\n'],
782
osutils.split_lines(u'foo\nbar\xae\n'))
784
def test_split_with_carriage_returns(self):
785
self.assertEqual(['foo\rbar\n'],
786
osutils.split_lines('foo\rbar\n'))
789
class TestWalkDirs(TestCaseInTempDir):
791
def test_walkdirs(self):
800
self.build_tree(tree)
801
expected_dirblocks = [
803
[('0file', '0file', 'file'),
804
('1dir', '1dir', 'directory'),
805
('2file', '2file', 'file'),
809
[('1dir/0file', '0file', 'file'),
810
('1dir/1dir', '1dir', 'directory'),
813
(('1dir/1dir', './1dir/1dir'),
820
for dirdetail, dirblock in osutils.walkdirs('.'):
821
if len(dirblock) and dirblock[0][1] == '.bzr':
822
# this tests the filtering of selected paths
825
result.append((dirdetail, dirblock))
827
self.assertTrue(found_bzrdir)
828
self.assertEqual(expected_dirblocks,
829
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
830
# you can search a subdir only, with a supplied prefix.
832
for dirblock in osutils.walkdirs('./1dir', '1dir'):
833
result.append(dirblock)
834
self.assertEqual(expected_dirblocks[1:],
835
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
837
def test__walkdirs_utf8(self):
846
self.build_tree(tree)
847
expected_dirblocks = [
849
[('0file', '0file', 'file'),
850
('1dir', '1dir', 'directory'),
851
('2file', '2file', 'file'),
855
[('1dir/0file', '0file', 'file'),
856
('1dir/1dir', '1dir', 'directory'),
859
(('1dir/1dir', './1dir/1dir'),
866
for dirdetail, dirblock in osutils._walkdirs_utf8('.'):
867
if len(dirblock) and dirblock[0][1] == '.bzr':
868
# this tests the filtering of selected paths
871
result.append((dirdetail, dirblock))
873
self.assertTrue(found_bzrdir)
874
self.assertEqual(expected_dirblocks,
875
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
876
# you can search a subdir only, with a supplied prefix.
878
for dirblock in osutils.walkdirs('./1dir', '1dir'):
879
result.append(dirblock)
880
self.assertEqual(expected_dirblocks[1:],
881
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
883
def _filter_out_stat(self, result):
884
"""Filter out the stat value from the walkdirs result"""
885
for dirdetail, dirblock in result:
887
for info in dirblock:
888
# Ignore info[3] which is the stat
889
new_dirblock.append((info[0], info[1], info[2], info[4]))
890
dirblock[:] = new_dirblock
892
def _save_platform_info(self):
893
cur_winver = win32utils.winver
894
cur_fs_enc = osutils._fs_enc
895
cur_dir_reader = osutils._selected_dir_reader
897
win32utils.winver = cur_winver
898
osutils._fs_enc = cur_fs_enc
899
osutils._selected_dir_reader = cur_dir_reader
900
self.addCleanup(restore)
902
def assertReadFSDirIs(self, expected):
903
"""Assert the right implementation for _walkdirs_utf8 is chosen."""
904
# Force it to redetect
905
osutils._selected_dir_reader = None
906
# Nothing to list, but should still trigger the selection logic
907
self.assertEqual([(('', '.'), [])], list(osutils._walkdirs_utf8('.')))
908
self.assertIsInstance(osutils._selected_dir_reader, expected)
910
def test_force_walkdirs_utf8_fs_utf8(self):
911
self.requireFeature(UTF8DirReaderFeature)
912
self._save_platform_info()
913
win32utils.winver = None # Avoid the win32 detection code
914
osutils._fs_enc = 'UTF-8'
915
self.assertReadFSDirIs(UTF8DirReaderFeature.reader)
917
def test_force_walkdirs_utf8_fs_ascii(self):
918
self.requireFeature(UTF8DirReaderFeature)
919
self._save_platform_info()
920
win32utils.winver = None # Avoid the win32 detection code
921
osutils._fs_enc = 'US-ASCII'
922
self.assertReadFSDirIs(UTF8DirReaderFeature.reader)
924
def test_force_walkdirs_utf8_fs_ANSI(self):
925
self.requireFeature(UTF8DirReaderFeature)
926
self._save_platform_info()
927
win32utils.winver = None # Avoid the win32 detection code
928
osutils._fs_enc = 'ANSI_X3.4-1968'
929
self.assertReadFSDirIs(UTF8DirReaderFeature.reader)
931
def test_force_walkdirs_utf8_fs_latin1(self):
932
self._save_platform_info()
933
win32utils.winver = None # Avoid the win32 detection code
934
osutils._fs_enc = 'latin1'
935
self.assertReadFSDirIs(osutils.UnicodeDirReader)
937
def test_force_walkdirs_utf8_nt(self):
938
# Disabled because the thunk of the whole walkdirs api is disabled.
939
self.requireFeature(Win32ReadDirFeature)
940
self._save_platform_info()
941
win32utils.winver = 'Windows NT'
942
from bzrlib._walkdirs_win32 import Win32ReadDir
943
self.assertReadFSDirIs(Win32ReadDir)
945
def test_force_walkdirs_utf8_98(self):
946
self.requireFeature(Win32ReadDirFeature)
947
self._save_platform_info()
948
win32utils.winver = 'Windows 98'
949
self.assertReadFSDirIs(osutils.UnicodeDirReader)
951
def test_unicode_walkdirs(self):
952
"""Walkdirs should always return unicode paths."""
953
name0 = u'0file-\xb6'
954
name1 = u'1dir-\u062c\u0648'
955
name2 = u'2file-\u0633'
960
name1 + '/' + name1 + '/',
964
self.build_tree(tree)
966
raise TestSkipped('Could not represent Unicode chars'
967
' in current encoding.')
968
expected_dirblocks = [
970
[(name0, name0, 'file', './' + name0),
971
(name1, name1, 'directory', './' + name1),
972
(name2, name2, 'file', './' + name2),
975
((name1, './' + name1),
976
[(name1 + '/' + name0, name0, 'file', './' + name1
978
(name1 + '/' + name1, name1, 'directory', './' + name1
982
((name1 + '/' + name1, './' + name1 + '/' + name1),
987
result = list(osutils.walkdirs('.'))
988
self._filter_out_stat(result)
989
self.assertEqual(expected_dirblocks, result)
990
result = list(osutils.walkdirs(u'./'+name1, name1))
991
self._filter_out_stat(result)
992
self.assertEqual(expected_dirblocks[1:], result)
994
def test_unicode__walkdirs_utf8(self):
995
"""Walkdirs_utf8 should always return utf8 paths.
997
The abspath portion might be in unicode or utf-8
999
name0 = u'0file-\xb6'
1000
name1 = u'1dir-\u062c\u0648'
1001
name2 = u'2file-\u0633'
1005
name1 + '/' + name0,
1006
name1 + '/' + name1 + '/',
1010
self.build_tree(tree)
1011
except UnicodeError:
1012
raise TestSkipped('Could not represent Unicode chars'
1013
' in current encoding.')
1014
name0 = name0.encode('utf8')
1015
name1 = name1.encode('utf8')
1016
name2 = name2.encode('utf8')
1018
expected_dirblocks = [
1020
[(name0, name0, 'file', './' + name0),
1021
(name1, name1, 'directory', './' + name1),
1022
(name2, name2, 'file', './' + name2),
1025
((name1, './' + name1),
1026
[(name1 + '/' + name0, name0, 'file', './' + name1
1028
(name1 + '/' + name1, name1, 'directory', './' + name1
1032
((name1 + '/' + name1, './' + name1 + '/' + name1),
1038
# For ease in testing, if walkdirs_utf8 returns Unicode, assert that
1039
# all abspaths are Unicode, and encode them back into utf8.
1040
for dirdetail, dirblock in osutils._walkdirs_utf8('.'):
1041
self.assertIsInstance(dirdetail[0], str)
1042
if isinstance(dirdetail[1], unicode):
1043
dirdetail = (dirdetail[0], dirdetail[1].encode('utf8'))
1044
dirblock = [list(info) for info in dirblock]
1045
for info in dirblock:
1046
self.assertIsInstance(info[4], unicode)
1047
info[4] = info[4].encode('utf8')
1049
for info in dirblock:
1050
self.assertIsInstance(info[0], str)
1051
self.assertIsInstance(info[1], str)
1052
self.assertIsInstance(info[4], str)
1053
# Remove the stat information
1054
new_dirblock.append((info[0], info[1], info[2], info[4]))
1055
result.append((dirdetail, new_dirblock))
1056
self.assertEqual(expected_dirblocks, result)
1058
def test__walkdirs_utf8_with_unicode_fs(self):
1059
"""UnicodeDirReader should be a safe fallback everywhere
1061
The abspath portion should be in unicode
1063
# Use the unicode reader. TODO: split into driver-and-driven unit
1065
self._save_platform_info()
1066
osutils._selected_dir_reader = osutils.UnicodeDirReader()
1067
name0u = u'0file-\xb6'
1068
name1u = u'1dir-\u062c\u0648'
1069
name2u = u'2file-\u0633'
1073
name1u + '/' + name0u,
1074
name1u + '/' + name1u + '/',
1078
self.build_tree(tree)
1079
except UnicodeError:
1080
raise TestSkipped('Could not represent Unicode chars'
1081
' in current encoding.')
1082
name0 = name0u.encode('utf8')
1083
name1 = name1u.encode('utf8')
1084
name2 = name2u.encode('utf8')
1086
# All of the abspaths should be in unicode, all of the relative paths
1088
expected_dirblocks = [
1090
[(name0, name0, 'file', './' + name0u),
1091
(name1, name1, 'directory', './' + name1u),
1092
(name2, name2, 'file', './' + name2u),
1095
((name1, './' + name1u),
1096
[(name1 + '/' + name0, name0, 'file', './' + name1u
1098
(name1 + '/' + name1, name1, 'directory', './' + name1u
1102
((name1 + '/' + name1, './' + name1u + '/' + name1u),
1107
result = list(osutils._walkdirs_utf8('.'))
1108
self._filter_out_stat(result)
1109
self.assertEqual(expected_dirblocks, result)
1111
def test__walkdirs_utf8_win32readdir(self):
1112
self.requireFeature(Win32ReadDirFeature)
1113
self.requireFeature(tests.UnicodeFilenameFeature)
1114
from bzrlib._walkdirs_win32 import Win32ReadDir
1115
self._save_platform_info()
1116
osutils._selected_dir_reader = Win32ReadDir()
1117
name0u = u'0file-\xb6'
1118
name1u = u'1dir-\u062c\u0648'
1119
name2u = u'2file-\u0633'
1123
name1u + '/' + name0u,
1124
name1u + '/' + name1u + '/',
1127
self.build_tree(tree)
1128
name0 = name0u.encode('utf8')
1129
name1 = name1u.encode('utf8')
1130
name2 = name2u.encode('utf8')
1132
# All of the abspaths should be in unicode, all of the relative paths
1134
expected_dirblocks = [
1136
[(name0, name0, 'file', './' + name0u),
1137
(name1, name1, 'directory', './' + name1u),
1138
(name2, name2, 'file', './' + name2u),
1141
((name1, './' + name1u),
1142
[(name1 + '/' + name0, name0, 'file', './' + name1u
1144
(name1 + '/' + name1, name1, 'directory', './' + name1u
1148
((name1 + '/' + name1, './' + name1u + '/' + name1u),
1153
result = list(osutils._walkdirs_utf8(u'.'))
1154
self._filter_out_stat(result)
1155
self.assertEqual(expected_dirblocks, result)
1157
def assertStatIsCorrect(self, path, win32stat):
1158
os_stat = os.stat(path)
1159
self.assertEqual(os_stat.st_size, win32stat.st_size)
1160
self.assertAlmostEqual(os_stat.st_mtime, win32stat.st_mtime, places=4)
1161
self.assertAlmostEqual(os_stat.st_ctime, win32stat.st_ctime, places=4)
1162
self.assertAlmostEqual(os_stat.st_atime, win32stat.st_atime, places=4)
1163
self.assertEqual(os_stat.st_dev, win32stat.st_dev)
1164
self.assertEqual(os_stat.st_ino, win32stat.st_ino)
1165
self.assertEqual(os_stat.st_mode, win32stat.st_mode)
1167
def test__walkdirs_utf_win32_find_file_stat_file(self):
1168
"""make sure our Stat values are valid"""
1169
self.requireFeature(Win32ReadDirFeature)
1170
self.requireFeature(tests.UnicodeFilenameFeature)
1171
from bzrlib._walkdirs_win32 import Win32ReadDir
1172
name0u = u'0file-\xb6'
1173
name0 = name0u.encode('utf8')
1174
self.build_tree([name0u])
1175
# I hate to sleep() here, but I'm trying to make the ctime different
1178
f = open(name0u, 'ab')
1180
f.write('just a small update')
1184
result = Win32ReadDir().read_dir('', u'.')
1186
self.assertEqual((name0, name0, 'file'), entry[:3])
1187
self.assertEqual(u'./' + name0u, entry[4])
1188
self.assertStatIsCorrect(entry[4], entry[3])
1189
self.assertNotEqual(entry[3].st_mtime, entry[3].st_ctime)
1191
def test__walkdirs_utf_win32_find_file_stat_directory(self):
1192
"""make sure our Stat values are valid"""
1193
self.requireFeature(Win32ReadDirFeature)
1194
self.requireFeature(tests.UnicodeFilenameFeature)
1195
from bzrlib._walkdirs_win32 import Win32ReadDir
1196
name0u = u'0dir-\u062c\u0648'
1197
name0 = name0u.encode('utf8')
1198
self.build_tree([name0u + '/'])
1200
result = Win32ReadDir().read_dir('', u'.')
1202
self.assertEqual((name0, name0, 'directory'), entry[:3])
1203
self.assertEqual(u'./' + name0u, entry[4])
1204
self.assertStatIsCorrect(entry[4], entry[3])
1206
def assertPathCompare(self, path_less, path_greater):
1207
"""check that path_less and path_greater compare correctly."""
1208
self.assertEqual(0, osutils.compare_paths_prefix_order(
1209
path_less, path_less))
1210
self.assertEqual(0, osutils.compare_paths_prefix_order(
1211
path_greater, path_greater))
1212
self.assertEqual(-1, osutils.compare_paths_prefix_order(
1213
path_less, path_greater))
1214
self.assertEqual(1, osutils.compare_paths_prefix_order(
1215
path_greater, path_less))
1217
def test_compare_paths_prefix_order(self):
1218
# root before all else
1219
self.assertPathCompare("/", "/a")
1220
# alpha within a dir
1221
self.assertPathCompare("/a", "/b")
1222
self.assertPathCompare("/b", "/z")
1223
# high dirs before lower.
1224
self.assertPathCompare("/z", "/a/a")
1225
# except if the deeper dir should be output first
1226
self.assertPathCompare("/a/b/c", "/d/g")
1227
# lexical betwen dirs of the same height
1228
self.assertPathCompare("/a/z", "/z/z")
1229
self.assertPathCompare("/a/c/z", "/a/d/e")
1231
# this should also be consistent for no leading / paths
1232
# root before all else
1233
self.assertPathCompare("", "a")
1234
# alpha within a dir
1235
self.assertPathCompare("a", "b")
1236
self.assertPathCompare("b", "z")
1237
# high dirs before lower.
1238
self.assertPathCompare("z", "a/a")
1239
# except if the deeper dir should be output first
1240
self.assertPathCompare("a/b/c", "d/g")
1241
# lexical betwen dirs of the same height
1242
self.assertPathCompare("a/z", "z/z")
1243
self.assertPathCompare("a/c/z", "a/d/e")
1245
def test_path_prefix_sorting(self):
1246
"""Doing a sort on path prefix should match our sample data."""
1261
dir_sorted_paths = [
1277
sorted(original_paths, key=osutils.path_prefix_key))
1278
# using the comparison routine shoudl work too:
1281
sorted(original_paths, cmp=osutils.compare_paths_prefix_order))
1284
class TestCopyTree(TestCaseInTempDir):
1286
def test_copy_basic_tree(self):
1287
self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c'])
1288
osutils.copy_tree('source', 'target')
1289
self.assertEqual(['a', 'b'], sorted(os.listdir('target')))
1290
self.assertEqual(['c'], os.listdir('target/b'))
1292
def test_copy_tree_target_exists(self):
1293
self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c',
1295
osutils.copy_tree('source', 'target')
1296
self.assertEqual(['a', 'b'], sorted(os.listdir('target')))
1297
self.assertEqual(['c'], os.listdir('target/b'))
1299
def test_copy_tree_symlinks(self):
1300
self.requireFeature(SymlinkFeature)
1301
self.build_tree(['source/'])
1302
os.symlink('a/generic/path', 'source/lnk')
1303
osutils.copy_tree('source', 'target')
1304
self.assertEqual(['lnk'], os.listdir('target'))
1305
self.assertEqual('a/generic/path', os.readlink('target/lnk'))
1307
def test_copy_tree_handlers(self):
1308
processed_files = []
1309
processed_links = []
1310
def file_handler(from_path, to_path):
1311
processed_files.append(('f', from_path, to_path))
1312
def dir_handler(from_path, to_path):
1313
processed_files.append(('d', from_path, to_path))
1314
def link_handler(from_path, to_path):
1315
processed_links.append((from_path, to_path))
1316
handlers = {'file':file_handler,
1317
'directory':dir_handler,
1318
'symlink':link_handler,
1321
self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c'])
1322
if osutils.has_symlinks():
1323
os.symlink('a/generic/path', 'source/lnk')
1324
osutils.copy_tree('source', 'target', handlers=handlers)
1326
self.assertEqual([('d', 'source', 'target'),
1327
('f', 'source/a', 'target/a'),
1328
('d', 'source/b', 'target/b'),
1329
('f', 'source/b/c', 'target/b/c'),
1331
self.failIfExists('target')
1332
if osutils.has_symlinks():
1333
self.assertEqual([('source/lnk', 'target/lnk')], processed_links)
1336
#class TestTerminalEncoding has been moved to test_osutils_encodings.py
1337
# [bialix] 2006/12/26
1340
class TestSetUnsetEnv(TestCase):
1341
"""Test updating the environment"""
1344
super(TestSetUnsetEnv, self).setUp()
1346
self.assertEqual(None, os.environ.get('BZR_TEST_ENV_VAR'),
1347
'Environment was not cleaned up properly.'
1348
' Variable BZR_TEST_ENV_VAR should not exist.')
1350
if 'BZR_TEST_ENV_VAR' in os.environ:
1351
del os.environ['BZR_TEST_ENV_VAR']
1353
self.addCleanup(cleanup)
1356
"""Test that we can set an env variable"""
1357
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
1358
self.assertEqual(None, old)
1359
self.assertEqual('foo', os.environ.get('BZR_TEST_ENV_VAR'))
1361
def test_double_set(self):
1362
"""Test that we get the old value out"""
1363
osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
1364
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'bar')
1365
self.assertEqual('foo', old)
1366
self.assertEqual('bar', os.environ.get('BZR_TEST_ENV_VAR'))
1368
def test_unicode(self):
1369
"""Environment can only contain plain strings
1371
So Unicode strings must be encoded.
1373
uni_val, env_val = probe_unicode_in_user_encoding()
1375
raise TestSkipped('Cannot find a unicode character that works in'
1376
' encoding %s' % (osutils.get_user_encoding(),))
1378
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', uni_val)
1379
self.assertEqual(env_val, os.environ.get('BZR_TEST_ENV_VAR'))
1381
def test_unset(self):
1382
"""Test that passing None will remove the env var"""
1383
osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
1384
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', None)
1385
self.assertEqual('foo', old)
1386
self.assertEqual(None, os.environ.get('BZR_TEST_ENV_VAR'))
1387
self.failIf('BZR_TEST_ENV_VAR' in os.environ)
1390
class TestLocalTimeOffset(TestCase):
1392
def test_local_time_offset(self):
1393
"""Test that local_time_offset() returns a sane value."""
1394
offset = osutils.local_time_offset()
1395
self.assertTrue(isinstance(offset, int))
1396
# Test that the offset is no more than a eighteen hours in
1398
# Time zone handling is system specific, so it is difficult to
1399
# do more specific tests, but a value outside of this range is
1401
eighteen_hours = 18 * 3600
1402
self.assertTrue(-eighteen_hours < offset < eighteen_hours)
1404
def test_local_time_offset_with_timestamp(self):
1405
"""Test that local_time_offset() works with a timestamp."""
1406
offset = osutils.local_time_offset(1000000000.1234567)
1407
self.assertTrue(isinstance(offset, int))
1408
eighteen_hours = 18 * 3600
1409
self.assertTrue(-eighteen_hours < offset < eighteen_hours)
1412
class TestShaFileByName(TestCaseInTempDir):
1414
def test_sha_empty(self):
1415
self.build_tree_contents([('foo', '')])
1416
expected_sha = osutils.sha_string('')
1417
self.assertEqual(expected_sha, osutils.sha_file_by_name('foo'))
1419
def test_sha_mixed_endings(self):
1420
text = 'test\r\nwith\nall\rpossible line endings\r\n'
1421
self.build_tree_contents([('foo', text)])
1422
expected_sha = osutils.sha_string(text)
1423
self.assertEqual(expected_sha, osutils.sha_file_by_name('foo'))
1427
r'''# Copyright (C) 2005, 2006 Canonical Ltd
1429
# This program is free software; you can redistribute it and/or modify
1430
# it under the terms of the GNU General Public License as published by
1431
# the Free Software Foundation; either version 2 of the License, or
1432
# (at your option) any later version.
1434
# This program is distributed in the hope that it will be useful,
1435
# but WITHOUT ANY WARRANTY; without even the implied warranty of
1436
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1437
# GNU General Public License for more details.
1439
# You should have received a copy of the GNU General Public License
1440
# along with this program; if not, write to the Free Software
1441
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1444
# NOTE: If update these, please also update the help for global-options in
1445
# bzrlib/help_topics/__init__.py
1448
"""Set of flags that enable different debug behaviour.
1450
These are set with eg ``-Dlock`` on the bzr command line.
1454
* auth - show authentication sections used
1455
* error - show stack traces for all top level exceptions
1456
* evil - capture call sites that do expensive or badly-scaling operations.
1457
* fetch - trace history copying between repositories
1458
* graph - trace graph traversal information
1459
* hashcache - log every time a working file is read to determine its hash
1460
* hooks - trace hook execution
1461
* hpss - trace smart protocol requests and responses
1462
* http - trace http connections, requests and responses
1463
* index - trace major index operations
1464
* knit - trace knit operations
1465
* lock - trace when lockdir locks are taken or released
1466
* merge - emit information for debugging merges
1467
* pack - emit information about pack operations
1473
class TestResourceLoading(TestCaseInTempDir):
1475
def test_resource_string(self):
1476
# test resource in bzrlib
1477
text = osutils.resource_string('bzrlib', 'debug.py')
1478
self.assertEquals(_debug_text, text)
1479
# test resource under bzrlib
1480
text = osutils.resource_string('bzrlib.ui', 'text.py')
1481
self.assertContainsRe(text, "class TextUIFactory")
1482
# test unsupported package
1483
self.assertRaises(errors.BzrError, osutils.resource_string, 'zzzz',
1485
# test unknown resource
1486
self.assertRaises(IOError, osutils.resource_string, 'bzrlib', 'yyy.xx')