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
class _UTF8DirReaderFeature(Feature):
64
from bzrlib import _readdir_pyx
65
self.reader = _readdir_pyx.UTF8DirReader
70
def feature_name(self):
71
return 'bzrlib._readdir_pyx'
73
UTF8DirReaderFeature = _UTF8DirReaderFeature()
76
class TestOSUtils(TestCaseInTempDir):
78
def test_contains_whitespace(self):
79
self.failUnless(osutils.contains_whitespace(u' '))
80
self.failUnless(osutils.contains_whitespace(u'hello there'))
81
self.failUnless(osutils.contains_whitespace(u'hellothere\n'))
82
self.failUnless(osutils.contains_whitespace(u'hello\nthere'))
83
self.failUnless(osutils.contains_whitespace(u'hello\rthere'))
84
self.failUnless(osutils.contains_whitespace(u'hello\tthere'))
86
# \xa0 is "Non-breaking-space" which on some python locales thinks it
87
# is whitespace, but we do not.
88
self.failIf(osutils.contains_whitespace(u''))
89
self.failIf(osutils.contains_whitespace(u'hellothere'))
90
self.failIf(osutils.contains_whitespace(u'hello\xa0there'))
92
def test_fancy_rename(self):
93
# This should work everywhere
95
osutils.fancy_rename(a, b,
96
rename_func=os.rename,
97
unlink_func=os.unlink)
99
open('a', 'wb').write('something in a\n')
101
self.failIfExists('a')
102
self.failUnlessExists('b')
103
self.check_file_contents('b', 'something in a\n')
105
open('a', 'wb').write('new something in a\n')
108
self.check_file_contents('a', 'something in a\n')
110
def test_rename(self):
111
# Rename should be semi-atomic on all platforms
112
open('a', 'wb').write('something in a\n')
113
osutils.rename('a', 'b')
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')
119
osutils.rename('b', 'a')
121
self.check_file_contents('a', 'something in a\n')
123
# TODO: test fancy_rename using a MemoryTransport
125
def test_rename_change_case(self):
126
# on Windows we should be able to change filename case by rename
127
self.build_tree(['a', 'b/'])
128
osutils.rename('a', 'A')
129
osutils.rename('b', 'B')
130
# we can't use failUnlessExists on case-insensitive filesystem
131
# so try to check shape of the tree
132
shape = sorted(os.listdir('.'))
133
self.assertEquals(['A', 'B'], shape)
135
def test_01_rand_chars_empty(self):
136
result = osutils.rand_chars(0)
137
self.assertEqual(result, '')
139
def test_02_rand_chars_100(self):
140
result = osutils.rand_chars(100)
141
self.assertEqual(len(result), 100)
142
self.assertEqual(type(result), str)
143
self.assertContainsRe(result, r'^[a-z0-9]{100}$')
145
def test_is_inside(self):
146
is_inside = osutils.is_inside
147
self.assertTrue(is_inside('src', 'src/foo.c'))
148
self.assertFalse(is_inside('src', 'srccontrol'))
149
self.assertTrue(is_inside('src', 'src/a/a/a/foo.c'))
150
self.assertTrue(is_inside('foo.c', 'foo.c'))
151
self.assertFalse(is_inside('foo.c', ''))
152
self.assertTrue(is_inside('', 'foo.c'))
154
def test_is_inside_any(self):
155
SRC_FOO_C = pathjoin('src', 'foo.c')
156
for dirs, fn in [(['src', 'doc'], SRC_FOO_C),
157
(['src'], SRC_FOO_C),
160
self.assert_(is_inside_any(dirs, fn))
161
for dirs, fn in [(['src'], 'srccontrol'),
162
(['src'], 'srccontrol/foo')]:
163
self.assertFalse(is_inside_any(dirs, fn))
165
def test_is_inside_or_parent_of_any(self):
166
for dirs, fn in [(['src', 'doc'], 'src/foo.c'),
167
(['src'], 'src/foo.c'),
168
(['src/bar.c'], 'src'),
169
(['src/bar.c', 'bla/foo.c'], 'src'),
172
self.assert_(is_inside_or_parent_of_any(dirs, fn))
174
for dirs, fn in [(['src'], 'srccontrol'),
175
(['srccontrol/foo.c'], 'src'),
176
(['src'], 'srccontrol/foo')]:
177
self.assertFalse(is_inside_or_parent_of_any(dirs, fn))
179
def test_rmtree(self):
180
# Check to remove tree with read-only files/dirs
182
f = file('dir/file', 'w')
185
# would like to also try making the directory readonly, but at the
186
# moment python shutil.rmtree doesn't handle that properly - it would
187
# need to chmod the directory before removing things inside it - deferred
188
# for now -- mbp 20060505
189
# osutils.make_readonly('dir')
190
osutils.make_readonly('dir/file')
192
osutils.rmtree('dir')
194
self.failIfExists('dir/file')
195
self.failIfExists('dir')
197
def test_file_kind(self):
198
self.build_tree(['file', 'dir/'])
199
self.assertEquals('file', osutils.file_kind('file'))
200
self.assertEquals('directory', osutils.file_kind('dir/'))
201
if osutils.has_symlinks():
202
os.symlink('symlink', 'symlink')
203
self.assertEquals('symlink', osutils.file_kind('symlink'))
205
# TODO: jam 20060529 Test a block device
207
os.lstat('/dev/null')
209
if e.errno not in (errno.ENOENT,):
212
self.assertEquals('chardev', osutils.file_kind('/dev/null'))
214
mkfifo = getattr(os, 'mkfifo', None)
218
self.assertEquals('fifo', osutils.file_kind('fifo'))
222
AF_UNIX = getattr(socket, 'AF_UNIX', None)
224
s = socket.socket(AF_UNIX)
227
self.assertEquals('socket', osutils.file_kind('socket'))
231
def test_kind_marker(self):
232
self.assertEqual(osutils.kind_marker('file'), '')
233
self.assertEqual(osutils.kind_marker('directory'), '/')
234
self.assertEqual(osutils.kind_marker('symlink'), '@')
235
self.assertEqual(osutils.kind_marker('tree-reference'), '+')
237
def test_get_umask(self):
238
if sys.platform == 'win32':
239
# umask always returns '0', no way to set it
240
self.assertEqual(0, osutils.get_umask())
243
orig_umask = osutils.get_umask()
246
self.assertEqual(0222, osutils.get_umask())
248
self.assertEqual(0022, osutils.get_umask())
250
self.assertEqual(0002, osutils.get_umask())
252
self.assertEqual(0027, osutils.get_umask())
256
def assertFormatedDelta(self, expected, seconds):
257
"""Assert osutils.format_delta formats as expected"""
258
actual = osutils.format_delta(seconds)
259
self.assertEqual(expected, actual)
261
def test_format_delta(self):
262
self.assertFormatedDelta('0 seconds ago', 0)
263
self.assertFormatedDelta('1 second ago', 1)
264
self.assertFormatedDelta('10 seconds ago', 10)
265
self.assertFormatedDelta('59 seconds ago', 59)
266
self.assertFormatedDelta('89 seconds ago', 89)
267
self.assertFormatedDelta('1 minute, 30 seconds ago', 90)
268
self.assertFormatedDelta('3 minutes, 0 seconds ago', 180)
269
self.assertFormatedDelta('3 minutes, 1 second ago', 181)
270
self.assertFormatedDelta('10 minutes, 15 seconds ago', 615)
271
self.assertFormatedDelta('30 minutes, 59 seconds ago', 1859)
272
self.assertFormatedDelta('31 minutes, 0 seconds ago', 1860)
273
self.assertFormatedDelta('60 minutes, 0 seconds ago', 3600)
274
self.assertFormatedDelta('89 minutes, 59 seconds ago', 5399)
275
self.assertFormatedDelta('1 hour, 30 minutes ago', 5400)
276
self.assertFormatedDelta('2 hours, 30 minutes ago', 9017)
277
self.assertFormatedDelta('10 hours, 0 minutes ago', 36000)
278
self.assertFormatedDelta('24 hours, 0 minutes ago', 86400)
279
self.assertFormatedDelta('35 hours, 59 minutes ago', 129599)
280
self.assertFormatedDelta('36 hours, 0 minutes ago', 129600)
281
self.assertFormatedDelta('36 hours, 0 minutes ago', 129601)
282
self.assertFormatedDelta('36 hours, 1 minute ago', 129660)
283
self.assertFormatedDelta('36 hours, 1 minute ago', 129661)
284
self.assertFormatedDelta('84 hours, 10 minutes ago', 303002)
286
# We handle when time steps the wrong direction because computers
287
# don't have synchronized clocks.
288
self.assertFormatedDelta('84 hours, 10 minutes in the future', -303002)
289
self.assertFormatedDelta('1 second in the future', -1)
290
self.assertFormatedDelta('2 seconds in the future', -2)
292
def test_format_date(self):
293
self.assertRaises(errors.UnsupportedTimezoneFormat,
294
osutils.format_date, 0, timezone='foo')
296
def test_dereference_path(self):
297
self.requireFeature(SymlinkFeature)
298
cwd = osutils.realpath('.')
300
bar_path = osutils.pathjoin(cwd, 'bar')
301
# Using './' to avoid bug #1213894 (first path component not
302
# dereferenced) in Python 2.4.1 and earlier
303
self.assertEqual(bar_path, osutils.realpath('./bar'))
304
os.symlink('bar', 'foo')
305
self.assertEqual(bar_path, osutils.realpath('./foo'))
307
# Does not dereference terminal symlinks
308
foo_path = osutils.pathjoin(cwd, 'foo')
309
self.assertEqual(foo_path, osutils.dereference_path('./foo'))
311
# Dereferences parent symlinks
313
baz_path = osutils.pathjoin(bar_path, 'baz')
314
self.assertEqual(baz_path, osutils.dereference_path('./foo/baz'))
316
# Dereferences parent symlinks that are the first path element
317
self.assertEqual(baz_path, osutils.dereference_path('foo/baz'))
319
# Dereferences parent symlinks in absolute paths
320
foo_baz_path = osutils.pathjoin(foo_path, 'baz')
321
self.assertEqual(baz_path, osutils.dereference_path(foo_baz_path))
323
def test_changing_access(self):
324
f = file('file', 'w')
328
# Make a file readonly
329
osutils.make_readonly('file')
330
mode = os.lstat('file').st_mode
331
self.assertEqual(mode, mode & 0777555)
333
# Make a file writable
334
osutils.make_writable('file')
335
mode = os.lstat('file').st_mode
336
self.assertEqual(mode, mode | 0200)
338
if osutils.has_symlinks():
339
# should not error when handed a symlink
340
os.symlink('nonexistent', 'dangling')
341
osutils.make_readonly('dangling')
342
osutils.make_writable('dangling')
344
def test_kind_marker(self):
345
self.assertEqual("", osutils.kind_marker("file"))
346
self.assertEqual("/", osutils.kind_marker(osutils._directory_kind))
347
self.assertEqual("@", osutils.kind_marker("symlink"))
348
self.assertRaises(errors.BzrError, osutils.kind_marker, "unknown")
350
def test_host_os_dereferences_symlinks(self):
351
osutils.host_os_dereferences_symlinks()
354
class TestPumpFile(TestCase):
355
"""Test pumpfile method."""
357
# create a test datablock
358
self.block_size = 512
359
pattern = '0123456789ABCDEF'
360
self.test_data = pattern * (3 * self.block_size / len(pattern))
361
self.test_data_len = len(self.test_data)
363
def test_bracket_block_size(self):
364
"""Read data in blocks with the requested read size bracketing the
366
# make sure test data is larger than max read size
367
self.assertTrue(self.test_data_len > self.block_size)
369
from_file = FakeReadFile(self.test_data)
372
# read (max / 2) bytes and verify read size wasn't affected
373
num_bytes_to_read = self.block_size / 2
374
pumpfile(from_file, to_file, num_bytes_to_read, self.block_size)
375
self.assertEqual(from_file.get_max_read_size(), num_bytes_to_read)
376
self.assertEqual(from_file.get_read_count(), 1)
378
# read (max) bytes and verify read size wasn't affected
379
num_bytes_to_read = self.block_size
380
from_file.reset_read_count()
381
pumpfile(from_file, to_file, num_bytes_to_read, self.block_size)
382
self.assertEqual(from_file.get_max_read_size(), num_bytes_to_read)
383
self.assertEqual(from_file.get_read_count(), 1)
385
# read (max + 1) bytes and verify read size was limited
386
num_bytes_to_read = self.block_size + 1
387
from_file.reset_read_count()
388
pumpfile(from_file, to_file, num_bytes_to_read, self.block_size)
389
self.assertEqual(from_file.get_max_read_size(), self.block_size)
390
self.assertEqual(from_file.get_read_count(), 2)
392
# finish reading the rest of the data
393
num_bytes_to_read = self.test_data_len - to_file.tell()
394
pumpfile(from_file, to_file, num_bytes_to_read, self.block_size)
396
# report error if the data wasn't equal (we only report the size due
397
# to the length of the data)
398
response_data = to_file.getvalue()
399
if response_data != self.test_data:
400
message = "Data not equal. Expected %d bytes, received %d."
401
self.fail(message % (len(response_data), self.test_data_len))
403
def test_specified_size(self):
404
"""Request a transfer larger than the maximum block size and verify
405
that the maximum read doesn't exceed the block_size."""
406
# make sure test data is larger than max read size
407
self.assertTrue(self.test_data_len > self.block_size)
409
# retrieve data in blocks
410
from_file = FakeReadFile(self.test_data)
412
pumpfile(from_file, to_file, self.test_data_len, self.block_size)
414
# verify read size was equal to the maximum read size
415
self.assertTrue(from_file.get_max_read_size() > 0)
416
self.assertEqual(from_file.get_max_read_size(), self.block_size)
417
self.assertEqual(from_file.get_read_count(), 3)
419
# report error if the data wasn't equal (we only report the size due
420
# to the length of the data)
421
response_data = to_file.getvalue()
422
if response_data != self.test_data:
423
message = "Data not equal. Expected %d bytes, received %d."
424
self.fail(message % (len(response_data), self.test_data_len))
426
def test_to_eof(self):
427
"""Read to end-of-file and verify that the reads are not larger than
428
the maximum read size."""
429
# make sure test data is larger than max read size
430
self.assertTrue(self.test_data_len > self.block_size)
432
# retrieve data to EOF
433
from_file = FakeReadFile(self.test_data)
435
pumpfile(from_file, to_file, -1, self.block_size)
437
# verify read size was equal to the maximum read size
438
self.assertEqual(from_file.get_max_read_size(), self.block_size)
439
self.assertEqual(from_file.get_read_count(), 4)
441
# report error if the data wasn't equal (we only report the size due
442
# to the length of the data)
443
response_data = to_file.getvalue()
444
if response_data != self.test_data:
445
message = "Data not equal. Expected %d bytes, received %d."
446
self.fail(message % (len(response_data), self.test_data_len))
448
def test_defaults(self):
449
"""Verifies that the default arguments will read to EOF -- this
450
test verifies that any existing usages of pumpfile will not be broken
451
with this new version."""
452
# retrieve data using default (old) pumpfile method
453
from_file = FakeReadFile(self.test_data)
455
pumpfile(from_file, to_file)
457
# report error if the data wasn't equal (we only report the size due
458
# to the length of the data)
459
response_data = to_file.getvalue()
460
if response_data != self.test_data:
461
message = "Data not equal. Expected %d bytes, received %d."
462
self.fail(message % (len(response_data), self.test_data_len))
465
class TestPumpStringFile(TestCase):
467
def test_empty(self):
469
pump_string_file("", output)
470
self.assertEqual("", output.getvalue())
472
def test_more_than_segment_size(self):
474
pump_string_file("123456789", output, 2)
475
self.assertEqual("123456789", output.getvalue())
477
def test_segment_size(self):
479
pump_string_file("12", output, 2)
480
self.assertEqual("12", output.getvalue())
482
def test_segment_size_multiple(self):
484
pump_string_file("1234", output, 2)
485
self.assertEqual("1234", output.getvalue())
488
class TestSafeUnicode(TestCase):
490
def test_from_ascii_string(self):
491
self.assertEqual(u'foobar', osutils.safe_unicode('foobar'))
493
def test_from_unicode_string_ascii_contents(self):
494
self.assertEqual(u'bargam', osutils.safe_unicode(u'bargam'))
496
def test_from_unicode_string_unicode_contents(self):
497
self.assertEqual(u'bargam\xae', osutils.safe_unicode(u'bargam\xae'))
499
def test_from_utf8_string(self):
500
self.assertEqual(u'foo\xae', osutils.safe_unicode('foo\xc2\xae'))
502
def test_bad_utf8_string(self):
503
self.assertRaises(BzrBadParameterNotUnicode,
504
osutils.safe_unicode,
508
class TestSafeUtf8(TestCase):
510
def test_from_ascii_string(self):
512
self.assertEqual('foobar', osutils.safe_utf8(f))
514
def test_from_unicode_string_ascii_contents(self):
515
self.assertEqual('bargam', osutils.safe_utf8(u'bargam'))
517
def test_from_unicode_string_unicode_contents(self):
518
self.assertEqual('bargam\xc2\xae', osutils.safe_utf8(u'bargam\xae'))
520
def test_from_utf8_string(self):
521
self.assertEqual('foo\xc2\xae', osutils.safe_utf8('foo\xc2\xae'))
523
def test_bad_utf8_string(self):
524
self.assertRaises(BzrBadParameterNotUnicode,
525
osutils.safe_utf8, '\xbb\xbb')
528
class TestSafeRevisionId(TestCase):
530
def test_from_ascii_string(self):
531
# this shouldn't give a warning because it's getting an ascii string
532
self.assertEqual('foobar', osutils.safe_revision_id('foobar'))
534
def test_from_unicode_string_ascii_contents(self):
535
self.assertEqual('bargam',
536
osutils.safe_revision_id(u'bargam', warn=False))
538
def test_from_unicode_deprecated(self):
539
self.assertEqual('bargam',
540
self.callDeprecated([osutils._revision_id_warning],
541
osutils.safe_revision_id, u'bargam'))
543
def test_from_unicode_string_unicode_contents(self):
544
self.assertEqual('bargam\xc2\xae',
545
osutils.safe_revision_id(u'bargam\xae', warn=False))
547
def test_from_utf8_string(self):
548
self.assertEqual('foo\xc2\xae',
549
osutils.safe_revision_id('foo\xc2\xae'))
552
"""Currently, None is a valid revision_id"""
553
self.assertEqual(None, osutils.safe_revision_id(None))
556
class TestSafeFileId(TestCase):
558
def test_from_ascii_string(self):
559
self.assertEqual('foobar', osutils.safe_file_id('foobar'))
561
def test_from_unicode_string_ascii_contents(self):
562
self.assertEqual('bargam', osutils.safe_file_id(u'bargam', warn=False))
564
def test_from_unicode_deprecated(self):
565
self.assertEqual('bargam',
566
self.callDeprecated([osutils._file_id_warning],
567
osutils.safe_file_id, u'bargam'))
569
def test_from_unicode_string_unicode_contents(self):
570
self.assertEqual('bargam\xc2\xae',
571
osutils.safe_file_id(u'bargam\xae', warn=False))
573
def test_from_utf8_string(self):
574
self.assertEqual('foo\xc2\xae',
575
osutils.safe_file_id('foo\xc2\xae'))
578
"""Currently, None is a valid revision_id"""
579
self.assertEqual(None, osutils.safe_file_id(None))
582
class TestWin32Funcs(TestCase):
583
"""Test that the _win32 versions of os utilities return appropriate paths."""
585
def test_abspath(self):
586
self.assertEqual('C:/foo', osutils._win32_abspath('C:\\foo'))
587
self.assertEqual('C:/foo', osutils._win32_abspath('C:/foo'))
588
self.assertEqual('//HOST/path', osutils._win32_abspath(r'\\HOST\path'))
589
self.assertEqual('//HOST/path', osutils._win32_abspath('//HOST/path'))
591
def test_realpath(self):
592
self.assertEqual('C:/foo', osutils._win32_realpath('C:\\foo'))
593
self.assertEqual('C:/foo', osutils._win32_realpath('C:/foo'))
595
def test_pathjoin(self):
596
self.assertEqual('path/to/foo', osutils._win32_pathjoin('path', 'to', 'foo'))
597
self.assertEqual('C:/foo', osutils._win32_pathjoin('path\\to', 'C:\\foo'))
598
self.assertEqual('C:/foo', osutils._win32_pathjoin('path/to', 'C:/foo'))
599
self.assertEqual('path/to/foo', osutils._win32_pathjoin('path/to/', 'foo'))
600
self.assertEqual('/foo', osutils._win32_pathjoin('C:/path/to/', '/foo'))
601
self.assertEqual('/foo', osutils._win32_pathjoin('C:\\path\\to\\', '\\foo'))
603
def test_normpath(self):
604
self.assertEqual('path/to/foo', osutils._win32_normpath(r'path\\from\..\to\.\foo'))
605
self.assertEqual('path/to/foo', osutils._win32_normpath('path//from/../to/./foo'))
607
def test_getcwd(self):
608
cwd = osutils._win32_getcwd()
609
os_cwd = os.getcwdu()
610
self.assertEqual(os_cwd[1:].replace('\\', '/'), cwd[1:])
611
# win32 is inconsistent whether it returns lower or upper case
612
# and even if it was consistent the user might type the other
613
# so we force it to uppercase
614
# running python.exe under cmd.exe return capital C:\\
615
# running win32 python inside a cygwin shell returns lowercase
616
self.assertEqual(os_cwd[0].upper(), cwd[0])
618
def test_fixdrive(self):
619
self.assertEqual('H:/foo', osutils._win32_fixdrive('h:/foo'))
620
self.assertEqual('H:/foo', osutils._win32_fixdrive('H:/foo'))
621
self.assertEqual('C:\\foo', osutils._win32_fixdrive('c:\\foo'))
623
def test_win98_abspath(self):
625
self.assertEqual('C:/foo', osutils._win98_abspath('C:\\foo'))
626
self.assertEqual('C:/foo', osutils._win98_abspath('C:/foo'))
628
self.assertEqual('//HOST/path', osutils._win98_abspath(r'\\HOST\path'))
629
self.assertEqual('//HOST/path', osutils._win98_abspath('//HOST/path'))
631
cwd = osutils.getcwd().rstrip('/')
632
drive = osutils._nt_splitdrive(cwd)[0]
633
self.assertEqual(cwd+'/path', osutils._win98_abspath('path'))
634
self.assertEqual(drive+'/path', osutils._win98_abspath('/path'))
637
self.assertEqual(cwd+'/'+u, osutils._win98_abspath(u))
640
class TestWin32FuncsDirs(TestCaseInTempDir):
641
"""Test win32 functions that create files."""
643
def test_getcwd(self):
644
if win32utils.winver == 'Windows 98':
645
raise TestSkipped('Windows 98 cannot handle unicode filenames')
646
# Make sure getcwd can handle unicode filenames
650
raise TestSkipped("Unable to create Unicode filename")
653
# TODO: jam 20060427 This will probably fail on Mac OSX because
654
# it will change the normalization of B\xe5gfors
655
# Consider using a different unicode character, or make
656
# osutils.getcwd() renormalize the path.
657
self.assertEndsWith(osutils._win32_getcwd(), u'mu-\xb5')
659
def test_minimum_path_selection(self):
660
self.assertEqual(set(),
661
osutils.minimum_path_selection([]))
662
self.assertEqual(set(['a', 'b']),
663
osutils.minimum_path_selection(['a', 'b']))
664
self.assertEqual(set(['a/', 'b']),
665
osutils.minimum_path_selection(['a/', 'b']))
666
self.assertEqual(set(['a/', 'b']),
667
osutils.minimum_path_selection(['a/c', 'a/', 'b']))
669
def test_mkdtemp(self):
670
tmpdir = osutils._win32_mkdtemp(dir='.')
671
self.assertFalse('\\' in tmpdir)
673
def test_rename(self):
681
osutils._win32_rename('b', 'a')
682
self.failUnlessExists('a')
683
self.failIfExists('b')
684
self.assertFileEqual('baz\n', 'a')
686
def test_rename_missing_file(self):
692
osutils._win32_rename('b', 'a')
693
except (IOError, OSError), e:
694
self.assertEqual(errno.ENOENT, e.errno)
695
self.assertFileEqual('foo\n', 'a')
697
def test_rename_missing_dir(self):
700
osutils._win32_rename('b', 'a')
701
except (IOError, OSError), e:
702
self.assertEqual(errno.ENOENT, e.errno)
704
def test_rename_current_dir(self):
707
# You can't rename the working directory
708
# doing rename non-existant . usually
709
# just raises ENOENT, since non-existant
712
osutils._win32_rename('b', '.')
713
except (IOError, OSError), e:
714
self.assertEqual(errno.ENOENT, e.errno)
716
def test_splitpath(self):
717
def check(expected, path):
718
self.assertEqual(expected, osutils.splitpath(path))
721
check(['a', 'b'], 'a/b')
722
check(['a', 'b'], 'a/./b')
723
check(['a', '.b'], 'a/.b')
724
check(['a', '.b'], 'a\\.b')
726
self.assertRaises(errors.BzrError, osutils.splitpath, 'a/../b')
729
class TestMacFuncsDirs(TestCaseInTempDir):
730
"""Test mac special functions that require directories."""
732
def test_getcwd(self):
733
# On Mac, this will actually create Ba\u030agfors
734
# but chdir will still work, because it accepts both paths
736
os.mkdir(u'B\xe5gfors')
738
raise TestSkipped("Unable to create Unicode filename")
740
os.chdir(u'B\xe5gfors')
741
self.assertEndsWith(osutils._mac_getcwd(), u'B\xe5gfors')
743
def test_getcwd_nonnorm(self):
744
# Test that _mac_getcwd() will normalize this path
746
os.mkdir(u'Ba\u030agfors')
748
raise TestSkipped("Unable to create Unicode filename")
750
os.chdir(u'Ba\u030agfors')
751
self.assertEndsWith(osutils._mac_getcwd(), u'B\xe5gfors')
754
class TestSplitLines(TestCase):
756
def test_split_unicode(self):
757
self.assertEqual([u'foo\n', u'bar\xae'],
758
osutils.split_lines(u'foo\nbar\xae'))
759
self.assertEqual([u'foo\n', u'bar\xae\n'],
760
osutils.split_lines(u'foo\nbar\xae\n'))
762
def test_split_with_carriage_returns(self):
763
self.assertEqual(['foo\rbar\n'],
764
osutils.split_lines('foo\rbar\n'))
767
class TestWalkDirs(TestCaseInTempDir):
769
def test_walkdirs(self):
778
self.build_tree(tree)
779
expected_dirblocks = [
781
[('0file', '0file', 'file'),
782
('1dir', '1dir', 'directory'),
783
('2file', '2file', 'file'),
787
[('1dir/0file', '0file', 'file'),
788
('1dir/1dir', '1dir', 'directory'),
791
(('1dir/1dir', './1dir/1dir'),
798
for dirdetail, dirblock in osutils.walkdirs('.'):
799
if len(dirblock) and dirblock[0][1] == '.bzr':
800
# this tests the filtering of selected paths
803
result.append((dirdetail, dirblock))
805
self.assertTrue(found_bzrdir)
806
self.assertEqual(expected_dirblocks,
807
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
808
# you can search a subdir only, with a supplied prefix.
810
for dirblock in osutils.walkdirs('./1dir', '1dir'):
811
result.append(dirblock)
812
self.assertEqual(expected_dirblocks[1:],
813
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
815
def test__walkdirs_utf8(self):
824
self.build_tree(tree)
825
expected_dirblocks = [
827
[('0file', '0file', 'file'),
828
('1dir', '1dir', 'directory'),
829
('2file', '2file', 'file'),
833
[('1dir/0file', '0file', 'file'),
834
('1dir/1dir', '1dir', 'directory'),
837
(('1dir/1dir', './1dir/1dir'),
844
for dirdetail, dirblock in osutils._walkdirs_utf8('.'):
845
if len(dirblock) and dirblock[0][1] == '.bzr':
846
# this tests the filtering of selected paths
849
result.append((dirdetail, dirblock))
851
self.assertTrue(found_bzrdir)
852
self.assertEqual(expected_dirblocks,
853
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
854
# you can search a subdir only, with a supplied prefix.
856
for dirblock in osutils.walkdirs('./1dir', '1dir'):
857
result.append(dirblock)
858
self.assertEqual(expected_dirblocks[1:],
859
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
861
def _filter_out_stat(self, result):
862
"""Filter out the stat value from the walkdirs result"""
863
for dirdetail, dirblock in result:
865
for info in dirblock:
866
# Ignore info[3] which is the stat
867
new_dirblock.append((info[0], info[1], info[2], info[4]))
868
dirblock[:] = new_dirblock
870
def _save_platform_info(self):
871
cur_winver = win32utils.winver
872
cur_fs_enc = osutils._fs_enc
873
cur_dir_reader = osutils._selected_dir_reader
875
win32utils.winver = cur_winver
876
osutils._fs_enc = cur_fs_enc
877
osutils._selected_dir_reader = cur_dir_reader
878
self.addCleanup(restore)
880
def assertReadFSDirIs(self, expected):
881
"""Assert the right implementation for _walkdirs_utf8 is chosen."""
882
# Force it to redetect
883
osutils._selected_dir_reader = None
884
# Nothing to list, but should still trigger the selection logic
885
self.assertEqual([(('', '.'), [])], list(osutils._walkdirs_utf8('.')))
886
self.assertIsInstance(osutils._selected_dir_reader, expected)
888
def test_force_walkdirs_utf8_fs_utf8(self):
889
self.requireFeature(UTF8DirReaderFeature)
890
self._save_platform_info()
891
win32utils.winver = None # Avoid the win32 detection code
892
osutils._fs_enc = 'UTF-8'
893
self.assertReadFSDirIs(UTF8DirReaderFeature.reader)
895
def test_force_walkdirs_utf8_fs_ascii(self):
896
self.requireFeature(UTF8DirReaderFeature)
897
self._save_platform_info()
898
win32utils.winver = None # Avoid the win32 detection code
899
osutils._fs_enc = 'US-ASCII'
900
self.assertReadFSDirIs(UTF8DirReaderFeature.reader)
902
def test_force_walkdirs_utf8_fs_ANSI(self):
903
self.requireFeature(UTF8DirReaderFeature)
904
self._save_platform_info()
905
win32utils.winver = None # Avoid the win32 detection code
906
osutils._fs_enc = 'ANSI_X3.4-1968'
907
self.assertReadFSDirIs(UTF8DirReaderFeature.reader)
909
def test_force_walkdirs_utf8_fs_latin1(self):
910
self._save_platform_info()
911
win32utils.winver = None # Avoid the win32 detection code
912
osutils._fs_enc = 'latin1'
913
self.assertReadFSDirIs(osutils.UnicodeDirReader)
915
def test_force_walkdirs_utf8_nt(self):
916
# Disabled because the thunk of the whole walkdirs api is disabled.
917
self.requireFeature(Win32ReadDirFeature)
918
self._save_platform_info()
919
win32utils.winver = 'Windows NT'
920
from bzrlib._walkdirs_win32 import Win32ReadDir
921
self.assertReadFSDirIs(Win32ReadDir)
923
def test_force_walkdirs_utf8_98(self):
924
self.requireFeature(Win32ReadDirFeature)
925
self._save_platform_info()
926
win32utils.winver = 'Windows 98'
927
self.assertReadFSDirIs(osutils.UnicodeDirReader)
929
def test_unicode_walkdirs(self):
930
"""Walkdirs should always return unicode paths."""
931
name0 = u'0file-\xb6'
932
name1 = u'1dir-\u062c\u0648'
933
name2 = u'2file-\u0633'
938
name1 + '/' + name1 + '/',
942
self.build_tree(tree)
944
raise TestSkipped('Could not represent Unicode chars'
945
' in current encoding.')
946
expected_dirblocks = [
948
[(name0, name0, 'file', './' + name0),
949
(name1, name1, 'directory', './' + name1),
950
(name2, name2, 'file', './' + name2),
953
((name1, './' + name1),
954
[(name1 + '/' + name0, name0, 'file', './' + name1
956
(name1 + '/' + name1, name1, 'directory', './' + name1
960
((name1 + '/' + name1, './' + name1 + '/' + name1),
965
result = list(osutils.walkdirs('.'))
966
self._filter_out_stat(result)
967
self.assertEqual(expected_dirblocks, result)
968
result = list(osutils.walkdirs(u'./'+name1, name1))
969
self._filter_out_stat(result)
970
self.assertEqual(expected_dirblocks[1:], result)
972
def test_unicode__walkdirs_utf8(self):
973
"""Walkdirs_utf8 should always return utf8 paths.
975
The abspath portion might be in unicode or utf-8
977
name0 = u'0file-\xb6'
978
name1 = u'1dir-\u062c\u0648'
979
name2 = u'2file-\u0633'
984
name1 + '/' + name1 + '/',
988
self.build_tree(tree)
990
raise TestSkipped('Could not represent Unicode chars'
991
' in current encoding.')
992
name0 = name0.encode('utf8')
993
name1 = name1.encode('utf8')
994
name2 = name2.encode('utf8')
996
expected_dirblocks = [
998
[(name0, name0, 'file', './' + name0),
999
(name1, name1, 'directory', './' + name1),
1000
(name2, name2, 'file', './' + name2),
1003
((name1, './' + name1),
1004
[(name1 + '/' + name0, name0, 'file', './' + name1
1006
(name1 + '/' + name1, name1, 'directory', './' + name1
1010
((name1 + '/' + name1, './' + name1 + '/' + name1),
1016
# For ease in testing, if walkdirs_utf8 returns Unicode, assert that
1017
# all abspaths are Unicode, and encode them back into utf8.
1018
for dirdetail, dirblock in osutils._walkdirs_utf8('.'):
1019
self.assertIsInstance(dirdetail[0], str)
1020
if isinstance(dirdetail[1], unicode):
1021
dirdetail = (dirdetail[0], dirdetail[1].encode('utf8'))
1022
dirblock = [list(info) for info in dirblock]
1023
for info in dirblock:
1024
self.assertIsInstance(info[4], unicode)
1025
info[4] = info[4].encode('utf8')
1027
for info in dirblock:
1028
self.assertIsInstance(info[0], str)
1029
self.assertIsInstance(info[1], str)
1030
self.assertIsInstance(info[4], str)
1031
# Remove the stat information
1032
new_dirblock.append((info[0], info[1], info[2], info[4]))
1033
result.append((dirdetail, new_dirblock))
1034
self.assertEqual(expected_dirblocks, result)
1036
def test__walkdirs_utf8_with_unicode_fs(self):
1037
"""UnicodeDirReader should be a safe fallback everywhere
1039
The abspath portion should be in unicode
1041
# Use the unicode reader. TODO: split into driver-and-driven unit
1043
self._save_platform_info()
1044
osutils._selected_dir_reader = osutils.UnicodeDirReader()
1045
name0u = u'0file-\xb6'
1046
name1u = u'1dir-\u062c\u0648'
1047
name2u = u'2file-\u0633'
1051
name1u + '/' + name0u,
1052
name1u + '/' + name1u + '/',
1056
self.build_tree(tree)
1057
except UnicodeError:
1058
raise TestSkipped('Could not represent Unicode chars'
1059
' in current encoding.')
1060
name0 = name0u.encode('utf8')
1061
name1 = name1u.encode('utf8')
1062
name2 = name2u.encode('utf8')
1064
# All of the abspaths should be in unicode, all of the relative paths
1066
expected_dirblocks = [
1068
[(name0, name0, 'file', './' + name0u),
1069
(name1, name1, 'directory', './' + name1u),
1070
(name2, name2, 'file', './' + name2u),
1073
((name1, './' + name1u),
1074
[(name1 + '/' + name0, name0, 'file', './' + name1u
1076
(name1 + '/' + name1, name1, 'directory', './' + name1u
1080
((name1 + '/' + name1, './' + name1u + '/' + name1u),
1085
result = list(osutils._walkdirs_utf8('.'))
1086
self._filter_out_stat(result)
1087
self.assertEqual(expected_dirblocks, result)
1089
def test__walkdirs_utf8_win32readdir(self):
1090
self.requireFeature(Win32ReadDirFeature)
1091
self.requireFeature(tests.UnicodeFilenameFeature)
1092
from bzrlib._walkdirs_win32 import Win32ReadDir
1093
self._save_platform_info()
1094
osutils._selected_dir_reader = Win32ReadDir()
1095
name0u = u'0file-\xb6'
1096
name1u = u'1dir-\u062c\u0648'
1097
name2u = u'2file-\u0633'
1101
name1u + '/' + name0u,
1102
name1u + '/' + name1u + '/',
1105
self.build_tree(tree)
1106
name0 = name0u.encode('utf8')
1107
name1 = name1u.encode('utf8')
1108
name2 = name2u.encode('utf8')
1110
# All of the abspaths should be in unicode, all of the relative paths
1112
expected_dirblocks = [
1114
[(name0, name0, 'file', './' + name0u),
1115
(name1, name1, 'directory', './' + name1u),
1116
(name2, name2, 'file', './' + name2u),
1119
((name1, './' + name1u),
1120
[(name1 + '/' + name0, name0, 'file', './' + name1u
1122
(name1 + '/' + name1, name1, 'directory', './' + name1u
1126
((name1 + '/' + name1, './' + name1u + '/' + name1u),
1131
result = list(osutils._walkdirs_utf8(u'.'))
1132
self._filter_out_stat(result)
1133
self.assertEqual(expected_dirblocks, result)
1135
def assertStatIsCorrect(self, path, win32stat):
1136
os_stat = os.stat(path)
1137
self.assertEqual(os_stat.st_size, win32stat.st_size)
1138
self.assertAlmostEqual(os_stat.st_mtime, win32stat.st_mtime, places=4)
1139
self.assertAlmostEqual(os_stat.st_ctime, win32stat.st_ctime, places=4)
1140
self.assertAlmostEqual(os_stat.st_atime, win32stat.st_atime, places=4)
1141
self.assertEqual(os_stat.st_dev, win32stat.st_dev)
1142
self.assertEqual(os_stat.st_ino, win32stat.st_ino)
1143
self.assertEqual(os_stat.st_mode, win32stat.st_mode)
1145
def test__walkdirs_utf_win32_find_file_stat_file(self):
1146
"""make sure our Stat values are valid"""
1147
self.requireFeature(Win32ReadDirFeature)
1148
self.requireFeature(tests.UnicodeFilenameFeature)
1149
from bzrlib._walkdirs_win32 import Win32ReadDir
1150
name0u = u'0file-\xb6'
1151
name0 = name0u.encode('utf8')
1152
self.build_tree([name0u])
1153
# I hate to sleep() here, but I'm trying to make the ctime different
1156
f = open(name0u, 'ab')
1158
f.write('just a small update')
1162
result = Win32ReadDir().read_dir('', u'.')
1164
self.assertEqual((name0, name0, 'file'), entry[:3])
1165
self.assertEqual(u'./' + name0u, entry[4])
1166
self.assertStatIsCorrect(entry[4], entry[3])
1167
self.assertNotEqual(entry[3].st_mtime, entry[3].st_ctime)
1169
def test__walkdirs_utf_win32_find_file_stat_directory(self):
1170
"""make sure our Stat values are valid"""
1171
self.requireFeature(Win32ReadDirFeature)
1172
self.requireFeature(tests.UnicodeFilenameFeature)
1173
from bzrlib._walkdirs_win32 import Win32ReadDir
1174
name0u = u'0dir-\u062c\u0648'
1175
name0 = name0u.encode('utf8')
1176
self.build_tree([name0u + '/'])
1178
result = Win32ReadDir().read_dir('', u'.')
1180
self.assertEqual((name0, name0, 'directory'), entry[:3])
1181
self.assertEqual(u'./' + name0u, entry[4])
1182
self.assertStatIsCorrect(entry[4], entry[3])
1184
def assertPathCompare(self, path_less, path_greater):
1185
"""check that path_less and path_greater compare correctly."""
1186
self.assertEqual(0, osutils.compare_paths_prefix_order(
1187
path_less, path_less))
1188
self.assertEqual(0, osutils.compare_paths_prefix_order(
1189
path_greater, path_greater))
1190
self.assertEqual(-1, osutils.compare_paths_prefix_order(
1191
path_less, path_greater))
1192
self.assertEqual(1, osutils.compare_paths_prefix_order(
1193
path_greater, path_less))
1195
def test_compare_paths_prefix_order(self):
1196
# root before all else
1197
self.assertPathCompare("/", "/a")
1198
# alpha within a dir
1199
self.assertPathCompare("/a", "/b")
1200
self.assertPathCompare("/b", "/z")
1201
# high dirs before lower.
1202
self.assertPathCompare("/z", "/a/a")
1203
# except if the deeper dir should be output first
1204
self.assertPathCompare("/a/b/c", "/d/g")
1205
# lexical betwen dirs of the same height
1206
self.assertPathCompare("/a/z", "/z/z")
1207
self.assertPathCompare("/a/c/z", "/a/d/e")
1209
# this should also be consistent for no leading / paths
1210
# root before all else
1211
self.assertPathCompare("", "a")
1212
# alpha within a dir
1213
self.assertPathCompare("a", "b")
1214
self.assertPathCompare("b", "z")
1215
# high dirs before lower.
1216
self.assertPathCompare("z", "a/a")
1217
# except if the deeper dir should be output first
1218
self.assertPathCompare("a/b/c", "d/g")
1219
# lexical betwen dirs of the same height
1220
self.assertPathCompare("a/z", "z/z")
1221
self.assertPathCompare("a/c/z", "a/d/e")
1223
def test_path_prefix_sorting(self):
1224
"""Doing a sort on path prefix should match our sample data."""
1239
dir_sorted_paths = [
1255
sorted(original_paths, key=osutils.path_prefix_key))
1256
# using the comparison routine shoudl work too:
1259
sorted(original_paths, cmp=osutils.compare_paths_prefix_order))
1262
class TestCopyTree(TestCaseInTempDir):
1264
def test_copy_basic_tree(self):
1265
self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c'])
1266
osutils.copy_tree('source', 'target')
1267
self.assertEqual(['a', 'b'], sorted(os.listdir('target')))
1268
self.assertEqual(['c'], os.listdir('target/b'))
1270
def test_copy_tree_target_exists(self):
1271
self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c',
1273
osutils.copy_tree('source', 'target')
1274
self.assertEqual(['a', 'b'], sorted(os.listdir('target')))
1275
self.assertEqual(['c'], os.listdir('target/b'))
1277
def test_copy_tree_symlinks(self):
1278
self.requireFeature(SymlinkFeature)
1279
self.build_tree(['source/'])
1280
os.symlink('a/generic/path', 'source/lnk')
1281
osutils.copy_tree('source', 'target')
1282
self.assertEqual(['lnk'], os.listdir('target'))
1283
self.assertEqual('a/generic/path', os.readlink('target/lnk'))
1285
def test_copy_tree_handlers(self):
1286
processed_files = []
1287
processed_links = []
1288
def file_handler(from_path, to_path):
1289
processed_files.append(('f', from_path, to_path))
1290
def dir_handler(from_path, to_path):
1291
processed_files.append(('d', from_path, to_path))
1292
def link_handler(from_path, to_path):
1293
processed_links.append((from_path, to_path))
1294
handlers = {'file':file_handler,
1295
'directory':dir_handler,
1296
'symlink':link_handler,
1299
self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c'])
1300
if osutils.has_symlinks():
1301
os.symlink('a/generic/path', 'source/lnk')
1302
osutils.copy_tree('source', 'target', handlers=handlers)
1304
self.assertEqual([('d', 'source', 'target'),
1305
('f', 'source/a', 'target/a'),
1306
('d', 'source/b', 'target/b'),
1307
('f', 'source/b/c', 'target/b/c'),
1309
self.failIfExists('target')
1310
if osutils.has_symlinks():
1311
self.assertEqual([('source/lnk', 'target/lnk')], processed_links)
1314
#class TestTerminalEncoding has been moved to test_osutils_encodings.py
1315
# [bialix] 2006/12/26
1318
class TestSetUnsetEnv(TestCase):
1319
"""Test updating the environment"""
1322
super(TestSetUnsetEnv, self).setUp()
1324
self.assertEqual(None, os.environ.get('BZR_TEST_ENV_VAR'),
1325
'Environment was not cleaned up properly.'
1326
' Variable BZR_TEST_ENV_VAR should not exist.')
1328
if 'BZR_TEST_ENV_VAR' in os.environ:
1329
del os.environ['BZR_TEST_ENV_VAR']
1331
self.addCleanup(cleanup)
1334
"""Test that we can set an env variable"""
1335
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
1336
self.assertEqual(None, old)
1337
self.assertEqual('foo', os.environ.get('BZR_TEST_ENV_VAR'))
1339
def test_double_set(self):
1340
"""Test that we get the old value out"""
1341
osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
1342
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'bar')
1343
self.assertEqual('foo', old)
1344
self.assertEqual('bar', os.environ.get('BZR_TEST_ENV_VAR'))
1346
def test_unicode(self):
1347
"""Environment can only contain plain strings
1349
So Unicode strings must be encoded.
1351
uni_val, env_val = probe_unicode_in_user_encoding()
1353
raise TestSkipped('Cannot find a unicode character that works in'
1354
' encoding %s' % (bzrlib.user_encoding,))
1356
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', uni_val)
1357
self.assertEqual(env_val, os.environ.get('BZR_TEST_ENV_VAR'))
1359
def test_unset(self):
1360
"""Test that passing None will remove the env var"""
1361
osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
1362
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', None)
1363
self.assertEqual('foo', old)
1364
self.assertEqual(None, os.environ.get('BZR_TEST_ENV_VAR'))
1365
self.failIf('BZR_TEST_ENV_VAR' in os.environ)
1368
class TestLocalTimeOffset(TestCase):
1370
def test_local_time_offset(self):
1371
"""Test that local_time_offset() returns a sane value."""
1372
offset = osutils.local_time_offset()
1373
self.assertTrue(isinstance(offset, int))
1374
# Test that the offset is no more than a eighteen hours in
1376
# Time zone handling is system specific, so it is difficult to
1377
# do more specific tests, but a value outside of this range is
1379
eighteen_hours = 18 * 3600
1380
self.assertTrue(-eighteen_hours < offset < eighteen_hours)
1382
def test_local_time_offset_with_timestamp(self):
1383
"""Test that local_time_offset() works with a timestamp."""
1384
offset = osutils.local_time_offset(1000000000.1234567)
1385
self.assertTrue(isinstance(offset, int))
1386
eighteen_hours = 18 * 3600
1387
self.assertTrue(-eighteen_hours < offset < eighteen_hours)
1390
class TestShaFileByName(TestCaseInTempDir):
1392
def test_sha_empty(self):
1393
self.build_tree_contents([('foo', '')])
1394
expected_sha = osutils.sha_string('')
1395
self.assertEqual(expected_sha, osutils.sha_file_by_name('foo'))
1397
def test_sha_mixed_endings(self):
1398
text = 'test\r\nwith\nall\rpossible line endings\r\n'
1399
self.build_tree_contents([('foo', text)])
1400
expected_sha = osutils.sha_string(text)
1401
self.assertEqual(expected_sha, osutils.sha_file_by_name('foo'))
1405
r'''# Copyright (C) 2005, 2006 Canonical Ltd
1407
# This program is free software; you can redistribute it and/or modify
1408
# it under the terms of the GNU General Public License as published by
1409
# the Free Software Foundation; either version 2 of the License, or
1410
# (at your option) any later version.
1412
# This program is distributed in the hope that it will be useful,
1413
# but WITHOUT ANY WARRANTY; without even the implied warranty of
1414
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1415
# GNU General Public License for more details.
1417
# You should have received a copy of the GNU General Public License
1418
# along with this program; if not, write to the Free Software
1419
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1422
# NOTE: If update these, please also update the help for global-options in
1423
# bzrlib/help_topics/__init__.py
1426
"""Set of flags that enable different debug behaviour.
1428
These are set with eg ``-Dlock`` on the bzr command line.
1432
* auth - show authentication sections used
1433
* error - show stack traces for all top level exceptions
1434
* evil - capture call sites that do expensive or badly-scaling operations.
1435
* fetch - trace history copying between repositories
1436
* graph - trace graph traversal information
1437
* hashcache - log every time a working file is read to determine its hash
1438
* hooks - trace hook execution
1439
* hpss - trace smart protocol requests and responses
1440
* http - trace http connections, requests and responses
1441
* index - trace major index operations
1442
* knit - trace knit operations
1443
* lock - trace when lockdir locks are taken or released
1444
* merge - emit information for debugging merges
1445
* pack - emit information about pack operations
1451
class TestResourceLoading(TestCaseInTempDir):
1453
def test_resource_string(self):
1454
# test resource in bzrlib
1455
text = osutils.resource_string('bzrlib', 'debug.py')
1456
self.assertEquals(_debug_text, text)
1457
# test resource under bzrlib
1458
text = osutils.resource_string('bzrlib.ui', 'text.py')
1459
self.assertContainsRe(text, "class TextUIFactory")
1460
# test unsupported package
1461
self.assertRaises(errors.BzrError, osutils.resource_string, 'zzzz',
1463
# test unknown resource
1464
self.assertRaises(IOError, osutils.resource_string, 'bzrlib', 'yyy.xx')