1
# Copyright (C) 2005, 2006 Canonical Ltd
2
# Authors: Robert Collins <robert.collins@canonical.com>
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
# GNU General Public License for more details.
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
"""Tests for finding and reading the bzr config file[s]."""
19
# import system imports here
20
from bzrlib.util.configobj.configobj import ConfigObj, ConfigObjError
21
from cStringIO import StringIO
25
#import bzrlib specific imports here
32
from bzrlib.branch import Branch
33
from bzrlib.bzrdir import BzrDir
34
from bzrlib.tests import TestCase, TestCaseInTempDir, TestCaseWithTransport
37
sample_long_alias="log -r-15..-1 --line"
38
sample_config_text = u"""
40
email=Erik B\u00e5gfors <erik@bagfors.nu>
42
gpg_signing_command=gnome-gpg
44
user_global_option=something
47
ll=""" + sample_long_alias + "\n"
50
sample_always_signatures = """
52
check_signatures=ignore
53
create_signatures=always
56
sample_ignore_signatures = """
58
check_signatures=require
59
create_signatures=never
62
sample_maybe_signatures = """
64
check_signatures=ignore
65
create_signatures=when-required
68
sample_branches_text = """
69
[http://www.example.com]
71
email=Robert Collins <robertc@example.org>
72
normal_option = normal
73
appendpath_option = append
74
appendpath_option:policy = appendpath
75
norecurse_option = norecurse
76
norecurse_option:policy = norecurse
77
[http://www.example.com/ignoreparent]
78
# different project: ignore parent dir config
80
[http://www.example.com/norecurse]
81
# configuration items that only apply to this dir
83
normal_option = norecurse
84
[http://www.example.com/dir]
85
appendpath_option = normal
87
check_signatures=require
88
# test trailing / matching with no children
90
check_signatures=check-available
91
gpg_signing_command=false
92
user_local_option=local
93
# test trailing / matching
95
#subdirs will match but not the parent
97
check_signatures=ignore
98
post_commit=bzrlib.tests.test_config.post_commit
99
#testing explicit beats globs
103
class InstrumentedConfigObj(object):
104
"""A config obj look-enough-alike to record calls made to it."""
106
def __contains__(self, thing):
107
self._calls.append(('__contains__', thing))
110
def __getitem__(self, key):
111
self._calls.append(('__getitem__', key))
114
def __init__(self, input, encoding=None):
115
self._calls = [('__init__', input, encoding)]
117
def __setitem__(self, key, value):
118
self._calls.append(('__setitem__', key, value))
120
def __delitem__(self, key):
121
self._calls.append(('__delitem__', key))
124
self._calls.append(('keys',))
127
def write(self, arg):
128
self._calls.append(('write',))
130
def as_bool(self, value):
131
self._calls.append(('as_bool', value))
134
def get_value(self, section, name):
135
self._calls.append(('get_value', section, name))
139
class FakeBranch(object):
141
def __init__(self, base=None, user_id=None):
143
self.base = "http://example.com/branches/demo"
146
self.control_files = FakeControlFiles(user_id=user_id)
148
def lock_write(self):
155
class FakeControlFiles(object):
157
def __init__(self, user_id=None):
161
def get_utf8(self, filename):
162
if filename != 'email':
163
raise NotImplementedError
164
if self.email is not None:
165
return StringIO(self.email)
166
raise errors.NoSuchFile(filename)
168
def get(self, filename):
170
return StringIO(self.files[filename])
172
raise errors.NoSuchFile(filename)
174
def put(self, filename, fileobj):
175
self.files[filename] = fileobj.read()
178
class InstrumentedConfig(config.Config):
179
"""An instrumented config that supplies stubs for template methods."""
182
super(InstrumentedConfig, self).__init__()
184
self._signatures = config.CHECK_NEVER
186
def _get_user_id(self):
187
self._calls.append('_get_user_id')
188
return "Robert Collins <robert.collins@example.org>"
190
def _get_signature_checking(self):
191
self._calls.append('_get_signature_checking')
192
return self._signatures
195
bool_config = """[DEFAULT]
202
class TestConfigObj(TestCase):
203
def test_get_bool(self):
204
from bzrlib.config import ConfigObj
205
co = ConfigObj(StringIO(bool_config))
206
self.assertIs(co.get_bool('DEFAULT', 'active'), True)
207
self.assertIs(co.get_bool('DEFAULT', 'inactive'), False)
208
self.assertIs(co.get_bool('UPPERCASE', 'active'), True)
209
self.assertIs(co.get_bool('UPPERCASE', 'nonactive'), False)
212
class TestConfig(TestCase):
214
def test_constructs(self):
217
def test_no_default_editor(self):
218
self.assertRaises(NotImplementedError, config.Config().get_editor)
220
def test_user_email(self):
221
my_config = InstrumentedConfig()
222
self.assertEqual('robert.collins@example.org', my_config.user_email())
223
self.assertEqual(['_get_user_id'], my_config._calls)
225
def test_username(self):
226
my_config = InstrumentedConfig()
227
self.assertEqual('Robert Collins <robert.collins@example.org>',
228
my_config.username())
229
self.assertEqual(['_get_user_id'], my_config._calls)
231
def test_signatures_default(self):
232
my_config = config.Config()
233
self.assertFalse(my_config.signature_needed())
234
self.assertEqual(config.CHECK_IF_POSSIBLE,
235
my_config.signature_checking())
236
self.assertEqual(config.SIGN_WHEN_REQUIRED,
237
my_config.signing_policy())
239
def test_signatures_template_method(self):
240
my_config = InstrumentedConfig()
241
self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
242
self.assertEqual(['_get_signature_checking'], my_config._calls)
244
def test_signatures_template_method_none(self):
245
my_config = InstrumentedConfig()
246
my_config._signatures = None
247
self.assertEqual(config.CHECK_IF_POSSIBLE,
248
my_config.signature_checking())
249
self.assertEqual(['_get_signature_checking'], my_config._calls)
251
def test_gpg_signing_command_default(self):
252
my_config = config.Config()
253
self.assertEqual('gpg', my_config.gpg_signing_command())
255
def test_get_user_option_default(self):
256
my_config = config.Config()
257
self.assertEqual(None, my_config.get_user_option('no_option'))
259
def test_post_commit_default(self):
260
my_config = config.Config()
261
self.assertEqual(None, my_config.post_commit())
263
def test_log_format_default(self):
264
my_config = config.Config()
265
self.assertEqual('long', my_config.log_format())
268
class TestConfigPath(TestCase):
271
super(TestConfigPath, self).setUp()
272
os.environ['HOME'] = '/home/bogus'
273
if sys.platform == 'win32':
274
os.environ['BZR_HOME'] = \
275
r'C:\Documents and Settings\bogus\Application Data'
277
def test_config_dir(self):
278
if sys.platform == 'win32':
279
self.assertEqual(config.config_dir(),
280
'C:/Documents and Settings/bogus/Application Data/bazaar/2.0')
282
self.assertEqual(config.config_dir(), '/home/bogus/.bazaar')
284
def test_config_filename(self):
285
if sys.platform == 'win32':
286
self.assertEqual(config.config_filename(),
287
'C:/Documents and Settings/bogus/Application Data/bazaar/2.0/bazaar.conf')
289
self.assertEqual(config.config_filename(),
290
'/home/bogus/.bazaar/bazaar.conf')
292
def test_branches_config_filename(self):
293
if sys.platform == 'win32':
294
self.assertEqual(config.branches_config_filename(),
295
'C:/Documents and Settings/bogus/Application Data/bazaar/2.0/branches.conf')
297
self.assertEqual(config.branches_config_filename(),
298
'/home/bogus/.bazaar/branches.conf')
300
def test_locations_config_filename(self):
301
if sys.platform == 'win32':
302
self.assertEqual(config.locations_config_filename(),
303
'C:/Documents and Settings/bogus/Application Data/bazaar/2.0/locations.conf')
305
self.assertEqual(config.locations_config_filename(),
306
'/home/bogus/.bazaar/locations.conf')
308
class TestIniConfig(TestCase):
310
def test_contructs(self):
311
my_config = config.IniBasedConfig("nothing")
313
def test_from_fp(self):
314
config_file = StringIO(sample_config_text.encode('utf-8'))
315
my_config = config.IniBasedConfig(None)
317
isinstance(my_config._get_parser(file=config_file),
320
def test_cached(self):
321
config_file = StringIO(sample_config_text.encode('utf-8'))
322
my_config = config.IniBasedConfig(None)
323
parser = my_config._get_parser(file=config_file)
324
self.failUnless(my_config._get_parser() is parser)
327
class TestGetConfig(TestCase):
329
def test_constructs(self):
330
my_config = config.GlobalConfig()
332
def test_calls_read_filenames(self):
333
# replace the class that is constructured, to check its parameters
334
oldparserclass = config.ConfigObj
335
config.ConfigObj = InstrumentedConfigObj
336
my_config = config.GlobalConfig()
338
parser = my_config._get_parser()
340
config.ConfigObj = oldparserclass
341
self.failUnless(isinstance(parser, InstrumentedConfigObj))
342
self.assertEqual(parser._calls, [('__init__', config.config_filename(),
346
class TestBranchConfig(TestCaseWithTransport):
348
def test_constructs(self):
349
branch = FakeBranch()
350
my_config = config.BranchConfig(branch)
351
self.assertRaises(TypeError, config.BranchConfig)
353
def test_get_location_config(self):
354
branch = FakeBranch()
355
my_config = config.BranchConfig(branch)
356
location_config = my_config._get_location_config()
357
self.assertEqual(branch.base, location_config.location)
358
self.failUnless(location_config is my_config._get_location_config())
360
def test_get_config(self):
361
"""The Branch.get_config method works properly"""
362
b = BzrDir.create_standalone_workingtree('.').branch
363
my_config = b.get_config()
364
self.assertIs(my_config.get_user_option('wacky'), None)
365
my_config.set_user_option('wacky', 'unlikely')
366
self.assertEqual(my_config.get_user_option('wacky'), 'unlikely')
368
# Ensure we get the same thing if we start again
369
b2 = Branch.open('.')
370
my_config2 = b2.get_config()
371
self.assertEqual(my_config2.get_user_option('wacky'), 'unlikely')
373
def test_has_explicit_nickname(self):
374
b = self.make_branch('.')
375
self.assertFalse(b.get_config().has_explicit_nickname())
377
self.assertTrue(b.get_config().has_explicit_nickname())
379
def test_config_url(self):
380
"""The Branch.get_config will use section that uses a local url"""
381
branch = self.make_branch('branch')
382
self.assertEqual('branch', branch.nick)
384
locations = config.locations_config_filename()
385
config.ensure_config_dir_exists()
386
local_url = urlutils.local_path_to_url('branch')
387
open(locations, 'wb').write('[%s]\nnickname = foobar'
389
self.assertEqual('foobar', branch.nick)
391
def test_config_local_path(self):
392
"""The Branch.get_config will use a local system path"""
393
branch = self.make_branch('branch')
394
self.assertEqual('branch', branch.nick)
396
locations = config.locations_config_filename()
397
config.ensure_config_dir_exists()
398
open(locations, 'wb').write('[%s/branch]\nnickname = barry'
399
% (osutils.getcwd().encode('utf8'),))
400
self.assertEqual('barry', branch.nick)
402
def test_config_creates_local(self):
403
"""Creating a new entry in config uses a local path."""
404
branch = self.make_branch('branch', format='knit')
405
branch.set_push_location('http://foobar')
406
locations = config.locations_config_filename()
407
local_path = osutils.getcwd().encode('utf8')
408
# Surprisingly ConfigObj doesn't create a trailing newline
409
self.check_file_contents(locations,
410
'[%s/branch]\npush_location = http://foobar\npush_location:policy = norecurse' % (local_path,))
412
def test_autonick_urlencoded(self):
413
b = self.make_branch('!repo')
414
self.assertEqual('!repo', b.get_config().get_nickname())
417
class TestGlobalConfigItems(TestCase):
419
def test_user_id(self):
420
config_file = StringIO(sample_config_text.encode('utf-8'))
421
my_config = config.GlobalConfig()
422
my_config._parser = my_config._get_parser(file=config_file)
423
self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
424
my_config._get_user_id())
426
def test_absent_user_id(self):
427
config_file = StringIO("")
428
my_config = config.GlobalConfig()
429
my_config._parser = my_config._get_parser(file=config_file)
430
self.assertEqual(None, my_config._get_user_id())
432
def test_configured_editor(self):
433
config_file = StringIO(sample_config_text.encode('utf-8'))
434
my_config = config.GlobalConfig()
435
my_config._parser = my_config._get_parser(file=config_file)
436
self.assertEqual("vim", my_config.get_editor())
438
def test_signatures_always(self):
439
config_file = StringIO(sample_always_signatures)
440
my_config = config.GlobalConfig()
441
my_config._parser = my_config._get_parser(file=config_file)
442
self.assertEqual(config.CHECK_NEVER,
443
my_config.signature_checking())
444
self.assertEqual(config.SIGN_ALWAYS,
445
my_config.signing_policy())
446
self.assertEqual(True, my_config.signature_needed())
448
def test_signatures_if_possible(self):
449
config_file = StringIO(sample_maybe_signatures)
450
my_config = config.GlobalConfig()
451
my_config._parser = my_config._get_parser(file=config_file)
452
self.assertEqual(config.CHECK_NEVER,
453
my_config.signature_checking())
454
self.assertEqual(config.SIGN_WHEN_REQUIRED,
455
my_config.signing_policy())
456
self.assertEqual(False, my_config.signature_needed())
458
def test_signatures_ignore(self):
459
config_file = StringIO(sample_ignore_signatures)
460
my_config = config.GlobalConfig()
461
my_config._parser = my_config._get_parser(file=config_file)
462
self.assertEqual(config.CHECK_ALWAYS,
463
my_config.signature_checking())
464
self.assertEqual(config.SIGN_NEVER,
465
my_config.signing_policy())
466
self.assertEqual(False, my_config.signature_needed())
468
def _get_sample_config(self):
469
config_file = StringIO(sample_config_text.encode('utf-8'))
470
my_config = config.GlobalConfig()
471
my_config._parser = my_config._get_parser(file=config_file)
474
def test_gpg_signing_command(self):
475
my_config = self._get_sample_config()
476
self.assertEqual("gnome-gpg", my_config.gpg_signing_command())
477
self.assertEqual(False, my_config.signature_needed())
479
def _get_empty_config(self):
480
config_file = StringIO("")
481
my_config = config.GlobalConfig()
482
my_config._parser = my_config._get_parser(file=config_file)
485
def test_gpg_signing_command_unset(self):
486
my_config = self._get_empty_config()
487
self.assertEqual("gpg", my_config.gpg_signing_command())
489
def test_get_user_option_default(self):
490
my_config = self._get_empty_config()
491
self.assertEqual(None, my_config.get_user_option('no_option'))
493
def test_get_user_option_global(self):
494
my_config = self._get_sample_config()
495
self.assertEqual("something",
496
my_config.get_user_option('user_global_option'))
498
def test_post_commit_default(self):
499
my_config = self._get_sample_config()
500
self.assertEqual(None, my_config.post_commit())
502
def test_configured_logformat(self):
503
my_config = self._get_sample_config()
504
self.assertEqual("short", my_config.log_format())
506
def test_get_alias(self):
507
my_config = self._get_sample_config()
508
self.assertEqual('help', my_config.get_alias('h'))
510
def test_get_no_alias(self):
511
my_config = self._get_sample_config()
512
self.assertEqual(None, my_config.get_alias('foo'))
514
def test_get_long_alias(self):
515
my_config = self._get_sample_config()
516
self.assertEqual(sample_long_alias, my_config.get_alias('ll'))
519
class TestLocationConfig(TestCaseInTempDir):
521
def test_constructs(self):
522
my_config = config.LocationConfig('http://example.com')
523
self.assertRaises(TypeError, config.LocationConfig)
525
def test_branch_calls_read_filenames(self):
526
# This is testing the correct file names are provided.
527
# TODO: consolidate with the test for GlobalConfigs filename checks.
529
# replace the class that is constructured, to check its parameters
530
oldparserclass = config.ConfigObj
531
config.ConfigObj = InstrumentedConfigObj
533
my_config = config.LocationConfig('http://www.example.com')
534
parser = my_config._get_parser()
536
config.ConfigObj = oldparserclass
537
self.failUnless(isinstance(parser, InstrumentedConfigObj))
538
self.assertEqual(parser._calls,
539
[('__init__', config.locations_config_filename(),
541
config.ensure_config_dir_exists()
542
#os.mkdir(config.config_dir())
543
f = file(config.branches_config_filename(), 'wb')
546
oldparserclass = config.ConfigObj
547
config.ConfigObj = InstrumentedConfigObj
549
my_config = config.LocationConfig('http://www.example.com')
550
parser = my_config._get_parser()
552
config.ConfigObj = oldparserclass
554
def test_get_global_config(self):
555
my_config = config.BranchConfig(FakeBranch('http://example.com'))
556
global_config = my_config._get_global_config()
557
self.failUnless(isinstance(global_config, config.GlobalConfig))
558
self.failUnless(global_config is my_config._get_global_config())
560
def test__get_matching_sections_no_match(self):
561
self.get_branch_config('/')
562
self.assertEqual([], self.my_location_config._get_matching_sections())
564
def test__get_matching_sections_exact(self):
565
self.get_branch_config('http://www.example.com')
566
self.assertEqual([('http://www.example.com', '')],
567
self.my_location_config._get_matching_sections())
569
def test__get_matching_sections_suffix_does_not(self):
570
self.get_branch_config('http://www.example.com-com')
571
self.assertEqual([], self.my_location_config._get_matching_sections())
573
def test__get_matching_sections_subdir_recursive(self):
574
self.get_branch_config('http://www.example.com/com')
575
self.assertEqual([('http://www.example.com', 'com')],
576
self.my_location_config._get_matching_sections())
578
def test__get_matching_sections_ignoreparent(self):
579
self.get_branch_config('http://www.example.com/ignoreparent')
580
self.assertEqual([('http://www.example.com/ignoreparent', '')],
581
self.my_location_config._get_matching_sections())
583
def test__get_matching_sections_ignoreparent_subdir(self):
584
self.get_branch_config(
585
'http://www.example.com/ignoreparent/childbranch')
586
self.assertEqual([('http://www.example.com/ignoreparent', 'childbranch')],
587
self.my_location_config._get_matching_sections())
589
def test__get_matching_sections_subdir_trailing_slash(self):
590
self.get_branch_config('/b')
591
self.assertEqual([('/b/', '')],
592
self.my_location_config._get_matching_sections())
594
def test__get_matching_sections_subdir_child(self):
595
self.get_branch_config('/a/foo')
596
self.assertEqual([('/a/*', ''), ('/a/', 'foo')],
597
self.my_location_config._get_matching_sections())
599
def test__get_matching_sections_subdir_child_child(self):
600
self.get_branch_config('/a/foo/bar')
601
self.assertEqual([('/a/*', 'bar'), ('/a/', 'foo/bar')],
602
self.my_location_config._get_matching_sections())
604
def test__get_matching_sections_trailing_slash_with_children(self):
605
self.get_branch_config('/a/')
606
self.assertEqual([('/a/', '')],
607
self.my_location_config._get_matching_sections())
609
def test__get_matching_sections_explicit_over_glob(self):
610
# XXX: 2006-09-08 jamesh
611
# This test only passes because ord('c') > ord('*'). If there
612
# was a config section for '/a/?', it would get precedence
614
self.get_branch_config('/a/c')
615
self.assertEqual([('/a/c', ''), ('/a/*', ''), ('/a/', 'c')],
616
self.my_location_config._get_matching_sections())
618
def test__get_option_policy_normal(self):
619
self.get_branch_config('http://www.example.com')
621
self.my_location_config._get_config_policy(
622
'http://www.example.com', 'normal_option'),
625
def test__get_option_policy_norecurse(self):
626
self.get_branch_config('http://www.example.com')
628
self.my_location_config._get_option_policy(
629
'http://www.example.com', 'norecurse_option'),
630
config.POLICY_NORECURSE)
631
# Test old recurse=False setting:
633
self.my_location_config._get_option_policy(
634
'http://www.example.com/norecurse', 'normal_option'),
635
config.POLICY_NORECURSE)
637
def test__get_option_policy_normal(self):
638
self.get_branch_config('http://www.example.com')
640
self.my_location_config._get_option_policy(
641
'http://www.example.com', 'appendpath_option'),
642
config.POLICY_APPENDPATH)
644
def test_location_without_username(self):
645
self.get_branch_config('http://www.example.com/ignoreparent')
646
self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
647
self.my_config.username())
649
def test_location_not_listed(self):
650
"""Test that the global username is used when no location matches"""
651
self.get_branch_config('/home/robertc/sources')
652
self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
653
self.my_config.username())
655
def test_overriding_location(self):
656
self.get_branch_config('http://www.example.com/foo')
657
self.assertEqual('Robert Collins <robertc@example.org>',
658
self.my_config.username())
660
def test_signatures_not_set(self):
661
self.get_branch_config('http://www.example.com',
662
global_config=sample_ignore_signatures)
663
self.assertEqual(config.CHECK_ALWAYS,
664
self.my_config.signature_checking())
665
self.assertEqual(config.SIGN_NEVER,
666
self.my_config.signing_policy())
668
def test_signatures_never(self):
669
self.get_branch_config('/a/c')
670
self.assertEqual(config.CHECK_NEVER,
671
self.my_config.signature_checking())
673
def test_signatures_when_available(self):
674
self.get_branch_config('/a/', global_config=sample_ignore_signatures)
675
self.assertEqual(config.CHECK_IF_POSSIBLE,
676
self.my_config.signature_checking())
678
def test_signatures_always(self):
679
self.get_branch_config('/b')
680
self.assertEqual(config.CHECK_ALWAYS,
681
self.my_config.signature_checking())
683
def test_gpg_signing_command(self):
684
self.get_branch_config('/b')
685
self.assertEqual("gnome-gpg", self.my_config.gpg_signing_command())
687
def test_gpg_signing_command_missing(self):
688
self.get_branch_config('/a')
689
self.assertEqual("false", self.my_config.gpg_signing_command())
691
def test_get_user_option_global(self):
692
self.get_branch_config('/a')
693
self.assertEqual('something',
694
self.my_config.get_user_option('user_global_option'))
696
def test_get_user_option_local(self):
697
self.get_branch_config('/a')
698
self.assertEqual('local',
699
self.my_config.get_user_option('user_local_option'))
701
def test_get_user_option_appendpath(self):
702
# returned as is for the base path:
703
self.get_branch_config('http://www.example.com')
704
self.assertEqual('append',
705
self.my_config.get_user_option('appendpath_option'))
706
# Extra path components get appended:
707
self.get_branch_config('http://www.example.com/a/b/c')
708
self.assertEqual('append/a/b/c',
709
self.my_config.get_user_option('appendpath_option'))
710
# Overriden for http://www.example.com/dir, where it is a
712
self.get_branch_config('http://www.example.com/dir/a/b/c')
713
self.assertEqual('normal',
714
self.my_config.get_user_option('appendpath_option'))
716
def test_get_user_option_norecurse(self):
717
self.get_branch_config('http://www.example.com')
718
self.assertEqual('norecurse',
719
self.my_config.get_user_option('norecurse_option'))
720
self.get_branch_config('http://www.example.com/dir')
721
self.assertEqual(None,
722
self.my_config.get_user_option('norecurse_option'))
723
# http://www.example.com/norecurse is a recurse=False section
724
# that redefines normal_option. Subdirectories do not pick up
726
self.get_branch_config('http://www.example.com/norecurse')
727
self.assertEqual('norecurse',
728
self.my_config.get_user_option('normal_option'))
729
self.get_branch_config('http://www.example.com/norecurse/subdir')
730
self.assertEqual('normal',
731
self.my_config.get_user_option('normal_option'))
733
def test_set_user_option_norecurse(self):
734
self.get_branch_config('http://www.example.com')
735
self.my_config.set_user_option('foo', 'bar',
736
store=config.STORE_LOCATION_NORECURSE)
738
self.my_location_config._get_option_policy(
739
'http://www.example.com', 'foo'),
740
config.POLICY_NORECURSE)
742
def test_set_user_option_appendpath(self):
743
self.get_branch_config('http://www.example.com')
744
self.my_config.set_user_option('foo', 'bar',
745
store=config.STORE_LOCATION_APPENDPATH)
747
self.my_location_config._get_option_policy(
748
'http://www.example.com', 'foo'),
749
config.POLICY_APPENDPATH)
751
def test_set_user_option_change_policy(self):
752
self.get_branch_config('http://www.example.com')
753
self.my_config.set_user_option('norecurse_option', 'normal',
754
store=config.STORE_LOCATION)
756
self.my_location_config._get_option_policy(
757
'http://www.example.com', 'norecurse_option'),
760
def test_set_user_option_recurse_false_section(self):
761
# The following section has recurse=False set. The test is to
762
# make sure that a normal option can be added to the section,
763
# converting recurse=False to the norecurse policy.
764
self.get_branch_config('http://www.example.com/norecurse')
765
self.callDeprecated(['The recurse option is deprecated as of 0.14. '
766
'The section "http://www.example.com/norecurse" '
767
'has been converted to use policies.'],
768
self.my_config.set_user_option,
769
'foo', 'bar', store=config.STORE_LOCATION)
771
self.my_location_config._get_option_policy(
772
'http://www.example.com/norecurse', 'foo'),
774
# The previously existing option is still norecurse:
776
self.my_location_config._get_option_policy(
777
'http://www.example.com/norecurse', 'normal_option'),
778
config.POLICY_NORECURSE)
781
def test_post_commit_default(self):
782
self.get_branch_config('/a/c')
783
self.assertEqual('bzrlib.tests.test_config.post_commit',
784
self.my_config.post_commit())
786
def get_branch_config(self, location, global_config=None):
787
if global_config is None:
788
global_file = StringIO(sample_config_text.encode('utf-8'))
790
global_file = StringIO(global_config.encode('utf-8'))
791
branches_file = StringIO(sample_branches_text.encode('utf-8'))
792
self.my_config = config.BranchConfig(FakeBranch(location))
793
# Force location config to use specified file
794
self.my_location_config = self.my_config._get_location_config()
795
self.my_location_config._get_parser(branches_file)
796
# Force global config to use specified file
797
self.my_config._get_global_config()._get_parser(global_file)
799
def test_set_user_setting_sets_and_saves(self):
800
self.get_branch_config('/a/c')
801
record = InstrumentedConfigObj("foo")
802
self.my_location_config._parser = record
804
real_mkdir = os.mkdir
806
def checked_mkdir(path, mode=0777):
807
self.log('making directory: %s', path)
808
real_mkdir(path, mode)
811
os.mkdir = checked_mkdir
813
self.callDeprecated(['The recurse option is deprecated as of '
814
'0.14. The section "/a/c" has been '
815
'converted to use policies.'],
816
self.my_config.set_user_option,
817
'foo', 'bar', store=config.STORE_LOCATION)
819
os.mkdir = real_mkdir
821
self.failUnless(self.created, 'Failed to create ~/.bazaar')
822
self.assertEqual([('__contains__', '/a/c'),
823
('__contains__', '/a/c/'),
824
('__setitem__', '/a/c', {}),
825
('__getitem__', '/a/c'),
826
('__setitem__', 'foo', 'bar'),
827
('__getitem__', '/a/c'),
828
('as_bool', 'recurse'),
829
('__getitem__', '/a/c'),
830
('__delitem__', 'recurse'),
831
('__getitem__', '/a/c'),
833
('__getitem__', '/a/c'),
834
('__contains__', 'foo:policy'),
838
def test_set_user_setting_sets_and_saves2(self):
839
self.get_branch_config('/a/c')
840
self.assertIs(self.my_config.get_user_option('foo'), None)
841
self.my_config.set_user_option('foo', 'bar')
843
self.my_config.branch.control_files.files['branch.conf'],
845
self.assertEqual(self.my_config.get_user_option('foo'), 'bar')
846
self.my_config.set_user_option('foo', 'baz',
847
store=config.STORE_LOCATION)
848
self.assertEqual(self.my_config.get_user_option('foo'), 'baz')
849
self.my_config.set_user_option('foo', 'qux')
850
self.assertEqual(self.my_config.get_user_option('foo'), 'baz')
853
precedence_global = 'option = global'
854
precedence_branch = 'option = branch'
855
precedence_location = """
859
[http://example.com/specific]
864
class TestBranchConfigItems(TestCaseInTempDir):
866
def get_branch_config(self, global_config=None, location=None,
867
location_config=None, branch_data_config=None):
868
my_config = config.BranchConfig(FakeBranch(location))
869
if global_config is not None:
870
global_file = StringIO(global_config.encode('utf-8'))
871
my_config._get_global_config()._get_parser(global_file)
872
self.my_location_config = my_config._get_location_config()
873
if location_config is not None:
874
location_file = StringIO(location_config.encode('utf-8'))
875
self.my_location_config._get_parser(location_file)
876
if branch_data_config is not None:
877
my_config.branch.control_files.files['branch.conf'] = \
881
def test_user_id(self):
882
branch = FakeBranch(user_id='Robert Collins <robertc@example.net>')
883
my_config = config.BranchConfig(branch)
884
self.assertEqual("Robert Collins <robertc@example.net>",
885
my_config.username())
886
branch.control_files.email = "John"
887
my_config.set_user_option('email',
888
"Robert Collins <robertc@example.org>")
889
self.assertEqual("John", my_config.username())
890
branch.control_files.email = None
891
self.assertEqual("Robert Collins <robertc@example.org>",
892
my_config.username())
894
def test_not_set_in_branch(self):
895
my_config = self.get_branch_config(sample_config_text)
896
my_config.branch.control_files.email = None
897
self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
898
my_config._get_user_id())
899
my_config.branch.control_files.email = "John"
900
self.assertEqual("John", my_config._get_user_id())
902
def test_BZR_EMAIL_OVERRIDES(self):
903
os.environ['BZR_EMAIL'] = "Robert Collins <robertc@example.org>"
904
branch = FakeBranch()
905
my_config = config.BranchConfig(branch)
906
self.assertEqual("Robert Collins <robertc@example.org>",
907
my_config.username())
909
def test_signatures_forced(self):
910
my_config = self.get_branch_config(
911
global_config=sample_always_signatures)
912
self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
913
self.assertEqual(config.SIGN_ALWAYS, my_config.signing_policy())
914
self.assertTrue(my_config.signature_needed())
916
def test_signatures_forced_branch(self):
917
my_config = self.get_branch_config(
918
global_config=sample_ignore_signatures,
919
branch_data_config=sample_always_signatures)
920
self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
921
self.assertEqual(config.SIGN_ALWAYS, my_config.signing_policy())
922
self.assertTrue(my_config.signature_needed())
924
def test_gpg_signing_command(self):
925
my_config = self.get_branch_config(
926
# branch data cannot set gpg_signing_command
927
branch_data_config="gpg_signing_command=pgp")
928
config_file = StringIO(sample_config_text.encode('utf-8'))
929
my_config._get_global_config()._get_parser(config_file)
930
self.assertEqual('gnome-gpg', my_config.gpg_signing_command())
932
def test_get_user_option_global(self):
933
branch = FakeBranch()
934
my_config = config.BranchConfig(branch)
935
config_file = StringIO(sample_config_text.encode('utf-8'))
936
(my_config._get_global_config()._get_parser(config_file))
937
self.assertEqual('something',
938
my_config.get_user_option('user_global_option'))
940
def test_post_commit_default(self):
941
branch = FakeBranch()
942
my_config = self.get_branch_config(sample_config_text, '/a/c',
943
sample_branches_text)
944
self.assertEqual(my_config.branch.base, '/a/c')
945
self.assertEqual('bzrlib.tests.test_config.post_commit',
946
my_config.post_commit())
947
my_config.set_user_option('post_commit', 'rmtree_root')
948
# post-commit is ignored when bresent in branch data
949
self.assertEqual('bzrlib.tests.test_config.post_commit',
950
my_config.post_commit())
951
my_config.set_user_option('post_commit', 'rmtree_root',
952
store=config.STORE_LOCATION)
953
self.assertEqual('rmtree_root', my_config.post_commit())
955
def test_config_precedence(self):
956
my_config = self.get_branch_config(global_config=precedence_global)
957
self.assertEqual(my_config.get_user_option('option'), 'global')
958
my_config = self.get_branch_config(global_config=precedence_global,
959
branch_data_config=precedence_branch)
960
self.assertEqual(my_config.get_user_option('option'), 'branch')
961
my_config = self.get_branch_config(global_config=precedence_global,
962
branch_data_config=precedence_branch,
963
location_config=precedence_location)
964
self.assertEqual(my_config.get_user_option('option'), 'recurse')
965
my_config = self.get_branch_config(global_config=precedence_global,
966
branch_data_config=precedence_branch,
967
location_config=precedence_location,
968
location='http://example.com/specific')
969
self.assertEqual(my_config.get_user_option('option'), 'exact')
972
class TestMailAddressExtraction(TestCase):
974
def test_extract_email_address(self):
975
self.assertEqual('jane@test.com',
976
config.extract_email_address('Jane <jane@test.com>'))
977
self.assertRaises(errors.NoEmailInUsername,
978
config.extract_email_address, 'Jane Tester')