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
33
from bzrlib.branch import Branch
34
from bzrlib.bzrdir import BzrDir
35
from bzrlib.tests import TestCase, TestCaseInTempDir, TestCaseWithTransport
38
sample_long_alias="log -r-15..-1 --line"
39
sample_config_text = u"""
41
email=Erik B\u00e5gfors <erik@bagfors.nu>
43
gpg_signing_command=gnome-gpg
45
user_global_option=something
48
ll=""" + sample_long_alias + "\n"
51
sample_always_signatures = """
53
check_signatures=ignore
54
create_signatures=always
57
sample_ignore_signatures = """
59
check_signatures=require
60
create_signatures=never
63
sample_maybe_signatures = """
65
check_signatures=ignore
66
create_signatures=when-required
69
sample_branches_text = """
70
[http://www.example.com]
72
email=Robert Collins <robertc@example.org>
73
normal_option = normal
74
appendpath_option = append
75
appendpath_option:policy = appendpath
76
norecurse_option = norecurse
77
norecurse_option:policy = norecurse
78
[http://www.example.com/ignoreparent]
79
# different project: ignore parent dir config
81
[http://www.example.com/norecurse]
82
# configuration items that only apply to this dir
84
normal_option = norecurse
85
[http://www.example.com/dir]
86
appendpath_option = normal
88
check_signatures=require
89
# test trailing / matching with no children
91
check_signatures=check-available
92
gpg_signing_command=false
93
user_local_option=local
94
# test trailing / matching
96
#subdirs will match but not the parent
98
check_signatures=ignore
99
post_commit=bzrlib.tests.test_config.post_commit
100
#testing explicit beats globs
104
class InstrumentedConfigObj(object):
105
"""A config obj look-enough-alike to record calls made to it."""
107
def __contains__(self, thing):
108
self._calls.append(('__contains__', thing))
111
def __getitem__(self, key):
112
self._calls.append(('__getitem__', key))
115
def __init__(self, input, encoding=None):
116
self._calls = [('__init__', input, encoding)]
118
def __setitem__(self, key, value):
119
self._calls.append(('__setitem__', key, value))
121
def __delitem__(self, key):
122
self._calls.append(('__delitem__', key))
125
self._calls.append(('keys',))
128
def write(self, arg):
129
self._calls.append(('write',))
131
def as_bool(self, value):
132
self._calls.append(('as_bool', value))
135
def get_value(self, section, name):
136
self._calls.append(('get_value', section, name))
140
class FakeBranch(object):
142
def __init__(self, base=None, user_id=None):
144
self.base = "http://example.com/branches/demo"
147
self.control_files = FakeControlFiles(user_id=user_id)
149
def lock_write(self):
156
class FakeControlFiles(object):
158
def __init__(self, user_id=None):
162
def get_utf8(self, filename):
163
if filename != 'email':
164
raise NotImplementedError
165
if self.email is not None:
166
return StringIO(self.email)
167
raise errors.NoSuchFile(filename)
169
def get(self, filename):
171
return StringIO(self.files[filename])
173
raise errors.NoSuchFile(filename)
175
def put(self, filename, fileobj):
176
self.files[filename] = fileobj.read()
179
class InstrumentedConfig(config.Config):
180
"""An instrumented config that supplies stubs for template methods."""
183
super(InstrumentedConfig, self).__init__()
185
self._signatures = config.CHECK_NEVER
187
def _get_user_id(self):
188
self._calls.append('_get_user_id')
189
return "Robert Collins <robert.collins@example.org>"
191
def _get_signature_checking(self):
192
self._calls.append('_get_signature_checking')
193
return self._signatures
196
bool_config = """[DEFAULT]
203
class TestConfigObj(TestCase):
204
def test_get_bool(self):
205
from bzrlib.config import ConfigObj
206
co = ConfigObj(StringIO(bool_config))
207
self.assertIs(co.get_bool('DEFAULT', 'active'), True)
208
self.assertIs(co.get_bool('DEFAULT', 'inactive'), False)
209
self.assertIs(co.get_bool('UPPERCASE', 'active'), True)
210
self.assertIs(co.get_bool('UPPERCASE', 'nonactive'), False)
213
class TestConfig(TestCase):
215
def test_constructs(self):
218
def test_no_default_editor(self):
219
self.assertRaises(NotImplementedError, config.Config().get_editor)
221
def test_user_email(self):
222
my_config = InstrumentedConfig()
223
self.assertEqual('robert.collins@example.org', my_config.user_email())
224
self.assertEqual(['_get_user_id'], my_config._calls)
226
def test_username(self):
227
my_config = InstrumentedConfig()
228
self.assertEqual('Robert Collins <robert.collins@example.org>',
229
my_config.username())
230
self.assertEqual(['_get_user_id'], my_config._calls)
232
def test_signatures_default(self):
233
my_config = config.Config()
234
self.assertFalse(my_config.signature_needed())
235
self.assertEqual(config.CHECK_IF_POSSIBLE,
236
my_config.signature_checking())
237
self.assertEqual(config.SIGN_WHEN_REQUIRED,
238
my_config.signing_policy())
240
def test_signatures_template_method(self):
241
my_config = InstrumentedConfig()
242
self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
243
self.assertEqual(['_get_signature_checking'], my_config._calls)
245
def test_signatures_template_method_none(self):
246
my_config = InstrumentedConfig()
247
my_config._signatures = None
248
self.assertEqual(config.CHECK_IF_POSSIBLE,
249
my_config.signature_checking())
250
self.assertEqual(['_get_signature_checking'], my_config._calls)
252
def test_gpg_signing_command_default(self):
253
my_config = config.Config()
254
self.assertEqual('gpg', my_config.gpg_signing_command())
256
def test_get_user_option_default(self):
257
my_config = config.Config()
258
self.assertEqual(None, my_config.get_user_option('no_option'))
260
def test_post_commit_default(self):
261
my_config = config.Config()
262
self.assertEqual(None, my_config.post_commit())
264
def test_log_format_default(self):
265
my_config = config.Config()
266
self.assertEqual('long', my_config.log_format())
269
class TestConfigPath(TestCase):
272
super(TestConfigPath, self).setUp()
273
os.environ['HOME'] = '/home/bogus'
274
if sys.platform == 'win32':
275
os.environ['BZR_HOME'] = \
276
r'C:\Documents and Settings\bogus\Application Data'
278
def test_config_dir(self):
279
if sys.platform == 'win32':
280
self.assertEqual(config.config_dir(),
281
'C:/Documents and Settings/bogus/Application Data/bazaar/2.0')
283
self.assertEqual(config.config_dir(), '/home/bogus/.bazaar')
285
def test_config_filename(self):
286
if sys.platform == 'win32':
287
self.assertEqual(config.config_filename(),
288
'C:/Documents and Settings/bogus/Application Data/bazaar/2.0/bazaar.conf')
290
self.assertEqual(config.config_filename(),
291
'/home/bogus/.bazaar/bazaar.conf')
293
def test_branches_config_filename(self):
294
if sys.platform == 'win32':
295
self.assertEqual(config.branches_config_filename(),
296
'C:/Documents and Settings/bogus/Application Data/bazaar/2.0/branches.conf')
298
self.assertEqual(config.branches_config_filename(),
299
'/home/bogus/.bazaar/branches.conf')
301
def test_locations_config_filename(self):
302
if sys.platform == 'win32':
303
self.assertEqual(config.locations_config_filename(),
304
'C:/Documents and Settings/bogus/Application Data/bazaar/2.0/locations.conf')
306
self.assertEqual(config.locations_config_filename(),
307
'/home/bogus/.bazaar/locations.conf')
309
class TestIniConfig(TestCase):
311
def test_contructs(self):
312
my_config = config.IniBasedConfig("nothing")
314
def test_from_fp(self):
315
config_file = StringIO(sample_config_text.encode('utf-8'))
316
my_config = config.IniBasedConfig(None)
318
isinstance(my_config._get_parser(file=config_file),
321
def test_cached(self):
322
config_file = StringIO(sample_config_text.encode('utf-8'))
323
my_config = config.IniBasedConfig(None)
324
parser = my_config._get_parser(file=config_file)
325
self.failUnless(my_config._get_parser() is parser)
328
class TestGetConfig(TestCase):
330
def test_constructs(self):
331
my_config = config.GlobalConfig()
333
def test_calls_read_filenames(self):
334
# replace the class that is constructured, to check its parameters
335
oldparserclass = config.ConfigObj
336
config.ConfigObj = InstrumentedConfigObj
337
my_config = config.GlobalConfig()
339
parser = my_config._get_parser()
341
config.ConfigObj = oldparserclass
342
self.failUnless(isinstance(parser, InstrumentedConfigObj))
343
self.assertEqual(parser._calls, [('__init__', config.config_filename(),
347
class TestBranchConfig(TestCaseWithTransport):
349
def test_constructs(self):
350
branch = FakeBranch()
351
my_config = config.BranchConfig(branch)
352
self.assertRaises(TypeError, config.BranchConfig)
354
def test_get_location_config(self):
355
branch = FakeBranch()
356
my_config = config.BranchConfig(branch)
357
location_config = my_config._get_location_config()
358
self.assertEqual(branch.base, location_config.location)
359
self.failUnless(location_config is my_config._get_location_config())
361
def test_get_config(self):
362
"""The Branch.get_config method works properly"""
363
b = BzrDir.create_standalone_workingtree('.').branch
364
my_config = b.get_config()
365
self.assertIs(my_config.get_user_option('wacky'), None)
366
my_config.set_user_option('wacky', 'unlikely')
367
self.assertEqual(my_config.get_user_option('wacky'), 'unlikely')
369
# Ensure we get the same thing if we start again
370
b2 = Branch.open('.')
371
my_config2 = b2.get_config()
372
self.assertEqual(my_config2.get_user_option('wacky'), 'unlikely')
374
def test_has_explicit_nickname(self):
375
b = self.make_branch('.')
376
self.assertFalse(b.get_config().has_explicit_nickname())
378
self.assertTrue(b.get_config().has_explicit_nickname())
380
def test_config_url(self):
381
"""The Branch.get_config will use section that uses a local url"""
382
branch = self.make_branch('branch')
383
self.assertEqual('branch', branch.nick)
385
locations = config.locations_config_filename()
386
config.ensure_config_dir_exists()
387
local_url = urlutils.local_path_to_url('branch')
388
open(locations, 'wb').write('[%s]\nnickname = foobar'
390
self.assertEqual('foobar', branch.nick)
392
def test_config_local_path(self):
393
"""The Branch.get_config will use a local system path"""
394
branch = self.make_branch('branch')
395
self.assertEqual('branch', branch.nick)
397
locations = config.locations_config_filename()
398
config.ensure_config_dir_exists()
399
open(locations, 'wb').write('[%s/branch]\nnickname = barry'
400
% (osutils.getcwd().encode('utf8'),))
401
self.assertEqual('barry', branch.nick)
403
def test_config_creates_local(self):
404
"""Creating a new entry in config uses a local path."""
405
branch = self.make_branch('branch', format='knit')
406
branch.set_push_location('http://foobar')
407
locations = config.locations_config_filename()
408
local_path = osutils.getcwd().encode('utf8')
409
# Surprisingly ConfigObj doesn't create a trailing newline
410
self.check_file_contents(locations,
411
'[%s/branch]\npush_location = http://foobar\npush_location:policy = norecurse' % (local_path,))
413
def test_autonick_urlencoded(self):
414
b = self.make_branch('!repo')
415
self.assertEqual('!repo', b.get_config().get_nickname())
417
def test_warn_if_masked(self):
418
_warning = trace.warning
421
warnings.append(args[0] % args[1:])
423
def set_option(store, warn_masked=True):
425
conf.set_user_option('example_option', repr(store), store=store,
426
warn_masked=warn_masked)
427
def assertWarning(warning):
429
self.assertEqual(0, len(warnings))
431
self.assertEqual(1, len(warnings))
432
self.assertEqual(warning, warnings[0])
433
trace.warning = warning
435
branch = self.make_branch('.')
436
conf = branch.get_config()
437
set_option(config.STORE_GLOBAL)
439
set_option(config.STORE_BRANCH)
441
set_option(config.STORE_GLOBAL)
442
assertWarning('Value "4" is masked by "3" from branch.conf')
443
set_option(config.STORE_GLOBAL, warn_masked=False)
445
set_option(config.STORE_LOCATION)
447
set_option(config.STORE_BRANCH)
448
assertWarning('Value "3" is masked by "0" from locations.conf')
449
set_option(config.STORE_BRANCH, warn_masked=False)
452
trace.warning = _warning
455
class TestGlobalConfigItems(TestCase):
457
def test_user_id(self):
458
config_file = StringIO(sample_config_text.encode('utf-8'))
459
my_config = config.GlobalConfig()
460
my_config._parser = my_config._get_parser(file=config_file)
461
self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
462
my_config._get_user_id())
464
def test_absent_user_id(self):
465
config_file = StringIO("")
466
my_config = config.GlobalConfig()
467
my_config._parser = my_config._get_parser(file=config_file)
468
self.assertEqual(None, my_config._get_user_id())
470
def test_configured_editor(self):
471
config_file = StringIO(sample_config_text.encode('utf-8'))
472
my_config = config.GlobalConfig()
473
my_config._parser = my_config._get_parser(file=config_file)
474
self.assertEqual("vim", my_config.get_editor())
476
def test_signatures_always(self):
477
config_file = StringIO(sample_always_signatures)
478
my_config = config.GlobalConfig()
479
my_config._parser = my_config._get_parser(file=config_file)
480
self.assertEqual(config.CHECK_NEVER,
481
my_config.signature_checking())
482
self.assertEqual(config.SIGN_ALWAYS,
483
my_config.signing_policy())
484
self.assertEqual(True, my_config.signature_needed())
486
def test_signatures_if_possible(self):
487
config_file = StringIO(sample_maybe_signatures)
488
my_config = config.GlobalConfig()
489
my_config._parser = my_config._get_parser(file=config_file)
490
self.assertEqual(config.CHECK_NEVER,
491
my_config.signature_checking())
492
self.assertEqual(config.SIGN_WHEN_REQUIRED,
493
my_config.signing_policy())
494
self.assertEqual(False, my_config.signature_needed())
496
def test_signatures_ignore(self):
497
config_file = StringIO(sample_ignore_signatures)
498
my_config = config.GlobalConfig()
499
my_config._parser = my_config._get_parser(file=config_file)
500
self.assertEqual(config.CHECK_ALWAYS,
501
my_config.signature_checking())
502
self.assertEqual(config.SIGN_NEVER,
503
my_config.signing_policy())
504
self.assertEqual(False, my_config.signature_needed())
506
def _get_sample_config(self):
507
config_file = StringIO(sample_config_text.encode('utf-8'))
508
my_config = config.GlobalConfig()
509
my_config._parser = my_config._get_parser(file=config_file)
512
def test_gpg_signing_command(self):
513
my_config = self._get_sample_config()
514
self.assertEqual("gnome-gpg", my_config.gpg_signing_command())
515
self.assertEqual(False, my_config.signature_needed())
517
def _get_empty_config(self):
518
config_file = StringIO("")
519
my_config = config.GlobalConfig()
520
my_config._parser = my_config._get_parser(file=config_file)
523
def test_gpg_signing_command_unset(self):
524
my_config = self._get_empty_config()
525
self.assertEqual("gpg", my_config.gpg_signing_command())
527
def test_get_user_option_default(self):
528
my_config = self._get_empty_config()
529
self.assertEqual(None, my_config.get_user_option('no_option'))
531
def test_get_user_option_global(self):
532
my_config = self._get_sample_config()
533
self.assertEqual("something",
534
my_config.get_user_option('user_global_option'))
536
def test_post_commit_default(self):
537
my_config = self._get_sample_config()
538
self.assertEqual(None, my_config.post_commit())
540
def test_configured_logformat(self):
541
my_config = self._get_sample_config()
542
self.assertEqual("short", my_config.log_format())
544
def test_get_alias(self):
545
my_config = self._get_sample_config()
546
self.assertEqual('help', my_config.get_alias('h'))
548
def test_get_no_alias(self):
549
my_config = self._get_sample_config()
550
self.assertEqual(None, my_config.get_alias('foo'))
552
def test_get_long_alias(self):
553
my_config = self._get_sample_config()
554
self.assertEqual(sample_long_alias, my_config.get_alias('ll'))
557
class TestLocationConfig(TestCaseInTempDir):
559
def test_constructs(self):
560
my_config = config.LocationConfig('http://example.com')
561
self.assertRaises(TypeError, config.LocationConfig)
563
def test_branch_calls_read_filenames(self):
564
# This is testing the correct file names are provided.
565
# TODO: consolidate with the test for GlobalConfigs filename checks.
567
# replace the class that is constructured, to check its parameters
568
oldparserclass = config.ConfigObj
569
config.ConfigObj = InstrumentedConfigObj
571
my_config = config.LocationConfig('http://www.example.com')
572
parser = my_config._get_parser()
574
config.ConfigObj = oldparserclass
575
self.failUnless(isinstance(parser, InstrumentedConfigObj))
576
self.assertEqual(parser._calls,
577
[('__init__', config.locations_config_filename(),
579
config.ensure_config_dir_exists()
580
#os.mkdir(config.config_dir())
581
f = file(config.branches_config_filename(), 'wb')
584
oldparserclass = config.ConfigObj
585
config.ConfigObj = InstrumentedConfigObj
587
my_config = config.LocationConfig('http://www.example.com')
588
parser = my_config._get_parser()
590
config.ConfigObj = oldparserclass
592
def test_get_global_config(self):
593
my_config = config.BranchConfig(FakeBranch('http://example.com'))
594
global_config = my_config._get_global_config()
595
self.failUnless(isinstance(global_config, config.GlobalConfig))
596
self.failUnless(global_config is my_config._get_global_config())
598
def test__get_matching_sections_no_match(self):
599
self.get_branch_config('/')
600
self.assertEqual([], self.my_location_config._get_matching_sections())
602
def test__get_matching_sections_exact(self):
603
self.get_branch_config('http://www.example.com')
604
self.assertEqual([('http://www.example.com', '')],
605
self.my_location_config._get_matching_sections())
607
def test__get_matching_sections_suffix_does_not(self):
608
self.get_branch_config('http://www.example.com-com')
609
self.assertEqual([], self.my_location_config._get_matching_sections())
611
def test__get_matching_sections_subdir_recursive(self):
612
self.get_branch_config('http://www.example.com/com')
613
self.assertEqual([('http://www.example.com', 'com')],
614
self.my_location_config._get_matching_sections())
616
def test__get_matching_sections_ignoreparent(self):
617
self.get_branch_config('http://www.example.com/ignoreparent')
618
self.assertEqual([('http://www.example.com/ignoreparent', '')],
619
self.my_location_config._get_matching_sections())
621
def test__get_matching_sections_ignoreparent_subdir(self):
622
self.get_branch_config(
623
'http://www.example.com/ignoreparent/childbranch')
624
self.assertEqual([('http://www.example.com/ignoreparent', 'childbranch')],
625
self.my_location_config._get_matching_sections())
627
def test__get_matching_sections_subdir_trailing_slash(self):
628
self.get_branch_config('/b')
629
self.assertEqual([('/b/', '')],
630
self.my_location_config._get_matching_sections())
632
def test__get_matching_sections_subdir_child(self):
633
self.get_branch_config('/a/foo')
634
self.assertEqual([('/a/*', ''), ('/a/', 'foo')],
635
self.my_location_config._get_matching_sections())
637
def test__get_matching_sections_subdir_child_child(self):
638
self.get_branch_config('/a/foo/bar')
639
self.assertEqual([('/a/*', 'bar'), ('/a/', 'foo/bar')],
640
self.my_location_config._get_matching_sections())
642
def test__get_matching_sections_trailing_slash_with_children(self):
643
self.get_branch_config('/a/')
644
self.assertEqual([('/a/', '')],
645
self.my_location_config._get_matching_sections())
647
def test__get_matching_sections_explicit_over_glob(self):
648
# XXX: 2006-09-08 jamesh
649
# This test only passes because ord('c') > ord('*'). If there
650
# was a config section for '/a/?', it would get precedence
652
self.get_branch_config('/a/c')
653
self.assertEqual([('/a/c', ''), ('/a/*', ''), ('/a/', 'c')],
654
self.my_location_config._get_matching_sections())
656
def test__get_option_policy_normal(self):
657
self.get_branch_config('http://www.example.com')
659
self.my_location_config._get_config_policy(
660
'http://www.example.com', 'normal_option'),
663
def test__get_option_policy_norecurse(self):
664
self.get_branch_config('http://www.example.com')
666
self.my_location_config._get_option_policy(
667
'http://www.example.com', 'norecurse_option'),
668
config.POLICY_NORECURSE)
669
# Test old recurse=False setting:
671
self.my_location_config._get_option_policy(
672
'http://www.example.com/norecurse', 'normal_option'),
673
config.POLICY_NORECURSE)
675
def test__get_option_policy_normal(self):
676
self.get_branch_config('http://www.example.com')
678
self.my_location_config._get_option_policy(
679
'http://www.example.com', 'appendpath_option'),
680
config.POLICY_APPENDPATH)
682
def test_location_without_username(self):
683
self.get_branch_config('http://www.example.com/ignoreparent')
684
self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
685
self.my_config.username())
687
def test_location_not_listed(self):
688
"""Test that the global username is used when no location matches"""
689
self.get_branch_config('/home/robertc/sources')
690
self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
691
self.my_config.username())
693
def test_overriding_location(self):
694
self.get_branch_config('http://www.example.com/foo')
695
self.assertEqual('Robert Collins <robertc@example.org>',
696
self.my_config.username())
698
def test_signatures_not_set(self):
699
self.get_branch_config('http://www.example.com',
700
global_config=sample_ignore_signatures)
701
self.assertEqual(config.CHECK_ALWAYS,
702
self.my_config.signature_checking())
703
self.assertEqual(config.SIGN_NEVER,
704
self.my_config.signing_policy())
706
def test_signatures_never(self):
707
self.get_branch_config('/a/c')
708
self.assertEqual(config.CHECK_NEVER,
709
self.my_config.signature_checking())
711
def test_signatures_when_available(self):
712
self.get_branch_config('/a/', global_config=sample_ignore_signatures)
713
self.assertEqual(config.CHECK_IF_POSSIBLE,
714
self.my_config.signature_checking())
716
def test_signatures_always(self):
717
self.get_branch_config('/b')
718
self.assertEqual(config.CHECK_ALWAYS,
719
self.my_config.signature_checking())
721
def test_gpg_signing_command(self):
722
self.get_branch_config('/b')
723
self.assertEqual("gnome-gpg", self.my_config.gpg_signing_command())
725
def test_gpg_signing_command_missing(self):
726
self.get_branch_config('/a')
727
self.assertEqual("false", self.my_config.gpg_signing_command())
729
def test_get_user_option_global(self):
730
self.get_branch_config('/a')
731
self.assertEqual('something',
732
self.my_config.get_user_option('user_global_option'))
734
def test_get_user_option_local(self):
735
self.get_branch_config('/a')
736
self.assertEqual('local',
737
self.my_config.get_user_option('user_local_option'))
739
def test_get_user_option_appendpath(self):
740
# returned as is for the base path:
741
self.get_branch_config('http://www.example.com')
742
self.assertEqual('append',
743
self.my_config.get_user_option('appendpath_option'))
744
# Extra path components get appended:
745
self.get_branch_config('http://www.example.com/a/b/c')
746
self.assertEqual('append/a/b/c',
747
self.my_config.get_user_option('appendpath_option'))
748
# Overriden for http://www.example.com/dir, where it is a
750
self.get_branch_config('http://www.example.com/dir/a/b/c')
751
self.assertEqual('normal',
752
self.my_config.get_user_option('appendpath_option'))
754
def test_get_user_option_norecurse(self):
755
self.get_branch_config('http://www.example.com')
756
self.assertEqual('norecurse',
757
self.my_config.get_user_option('norecurse_option'))
758
self.get_branch_config('http://www.example.com/dir')
759
self.assertEqual(None,
760
self.my_config.get_user_option('norecurse_option'))
761
# http://www.example.com/norecurse is a recurse=False section
762
# that redefines normal_option. Subdirectories do not pick up
764
self.get_branch_config('http://www.example.com/norecurse')
765
self.assertEqual('norecurse',
766
self.my_config.get_user_option('normal_option'))
767
self.get_branch_config('http://www.example.com/norecurse/subdir')
768
self.assertEqual('normal',
769
self.my_config.get_user_option('normal_option'))
771
def test_set_user_option_norecurse(self):
772
self.get_branch_config('http://www.example.com')
773
self.my_config.set_user_option('foo', 'bar',
774
store=config.STORE_LOCATION_NORECURSE)
776
self.my_location_config._get_option_policy(
777
'http://www.example.com', 'foo'),
778
config.POLICY_NORECURSE)
780
def test_set_user_option_appendpath(self):
781
self.get_branch_config('http://www.example.com')
782
self.my_config.set_user_option('foo', 'bar',
783
store=config.STORE_LOCATION_APPENDPATH)
785
self.my_location_config._get_option_policy(
786
'http://www.example.com', 'foo'),
787
config.POLICY_APPENDPATH)
789
def test_set_user_option_change_policy(self):
790
self.get_branch_config('http://www.example.com')
791
self.my_config.set_user_option('norecurse_option', 'normal',
792
store=config.STORE_LOCATION)
794
self.my_location_config._get_option_policy(
795
'http://www.example.com', 'norecurse_option'),
798
def test_set_user_option_recurse_false_section(self):
799
# The following section has recurse=False set. The test is to
800
# make sure that a normal option can be added to the section,
801
# converting recurse=False to the norecurse policy.
802
self.get_branch_config('http://www.example.com/norecurse')
803
self.callDeprecated(['The recurse option is deprecated as of 0.14. '
804
'The section "http://www.example.com/norecurse" '
805
'has been converted to use policies.'],
806
self.my_config.set_user_option,
807
'foo', 'bar', store=config.STORE_LOCATION)
809
self.my_location_config._get_option_policy(
810
'http://www.example.com/norecurse', 'foo'),
812
# The previously existing option is still norecurse:
814
self.my_location_config._get_option_policy(
815
'http://www.example.com/norecurse', 'normal_option'),
816
config.POLICY_NORECURSE)
818
def test_post_commit_default(self):
819
self.get_branch_config('/a/c')
820
self.assertEqual('bzrlib.tests.test_config.post_commit',
821
self.my_config.post_commit())
823
def get_branch_config(self, location, global_config=None):
824
if global_config is None:
825
global_file = StringIO(sample_config_text.encode('utf-8'))
827
global_file = StringIO(global_config.encode('utf-8'))
828
branches_file = StringIO(sample_branches_text.encode('utf-8'))
829
self.my_config = config.BranchConfig(FakeBranch(location))
830
# Force location config to use specified file
831
self.my_location_config = self.my_config._get_location_config()
832
self.my_location_config._get_parser(branches_file)
833
# Force global config to use specified file
834
self.my_config._get_global_config()._get_parser(global_file)
836
def test_set_user_setting_sets_and_saves(self):
837
self.get_branch_config('/a/c')
838
record = InstrumentedConfigObj("foo")
839
self.my_location_config._parser = record
841
real_mkdir = os.mkdir
843
def checked_mkdir(path, mode=0777):
844
self.log('making directory: %s', path)
845
real_mkdir(path, mode)
848
os.mkdir = checked_mkdir
850
self.callDeprecated(['The recurse option is deprecated as of '
851
'0.14. The section "/a/c" has been '
852
'converted to use policies.'],
853
self.my_config.set_user_option,
854
'foo', 'bar', store=config.STORE_LOCATION)
856
os.mkdir = real_mkdir
858
self.failUnless(self.created, 'Failed to create ~/.bazaar')
859
self.assertEqual([('__contains__', '/a/c'),
860
('__contains__', '/a/c/'),
861
('__setitem__', '/a/c', {}),
862
('__getitem__', '/a/c'),
863
('__setitem__', 'foo', 'bar'),
864
('__getitem__', '/a/c'),
865
('as_bool', 'recurse'),
866
('__getitem__', '/a/c'),
867
('__delitem__', 'recurse'),
868
('__getitem__', '/a/c'),
870
('__getitem__', '/a/c'),
871
('__contains__', 'foo:policy'),
875
def test_set_user_setting_sets_and_saves2(self):
876
self.get_branch_config('/a/c')
877
self.assertIs(self.my_config.get_user_option('foo'), None)
878
self.my_config.set_user_option('foo', 'bar')
880
self.my_config.branch.control_files.files['branch.conf'],
882
self.assertEqual(self.my_config.get_user_option('foo'), 'bar')
883
self.my_config.set_user_option('foo', 'baz',
884
store=config.STORE_LOCATION)
885
self.assertEqual(self.my_config.get_user_option('foo'), 'baz')
886
self.my_config.set_user_option('foo', 'qux')
887
self.assertEqual(self.my_config.get_user_option('foo'), 'baz')
890
precedence_global = 'option = global'
891
precedence_branch = 'option = branch'
892
precedence_location = """
896
[http://example.com/specific]
901
class TestBranchConfigItems(TestCaseInTempDir):
903
def get_branch_config(self, global_config=None, location=None,
904
location_config=None, branch_data_config=None):
905
my_config = config.BranchConfig(FakeBranch(location))
906
if global_config is not None:
907
global_file = StringIO(global_config.encode('utf-8'))
908
my_config._get_global_config()._get_parser(global_file)
909
self.my_location_config = my_config._get_location_config()
910
if location_config is not None:
911
location_file = StringIO(location_config.encode('utf-8'))
912
self.my_location_config._get_parser(location_file)
913
if branch_data_config is not None:
914
my_config.branch.control_files.files['branch.conf'] = \
918
def test_user_id(self):
919
branch = FakeBranch(user_id='Robert Collins <robertc@example.net>')
920
my_config = config.BranchConfig(branch)
921
self.assertEqual("Robert Collins <robertc@example.net>",
922
my_config.username())
923
branch.control_files.email = "John"
924
my_config.set_user_option('email',
925
"Robert Collins <robertc@example.org>")
926
self.assertEqual("John", my_config.username())
927
branch.control_files.email = None
928
self.assertEqual("Robert Collins <robertc@example.org>",
929
my_config.username())
931
def test_not_set_in_branch(self):
932
my_config = self.get_branch_config(sample_config_text)
933
my_config.branch.control_files.email = None
934
self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
935
my_config._get_user_id())
936
my_config.branch.control_files.email = "John"
937
self.assertEqual("John", my_config._get_user_id())
939
def test_BZR_EMAIL_OVERRIDES(self):
940
os.environ['BZR_EMAIL'] = "Robert Collins <robertc@example.org>"
941
branch = FakeBranch()
942
my_config = config.BranchConfig(branch)
943
self.assertEqual("Robert Collins <robertc@example.org>",
944
my_config.username())
946
def test_signatures_forced(self):
947
my_config = self.get_branch_config(
948
global_config=sample_always_signatures)
949
self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
950
self.assertEqual(config.SIGN_ALWAYS, my_config.signing_policy())
951
self.assertTrue(my_config.signature_needed())
953
def test_signatures_forced_branch(self):
954
my_config = self.get_branch_config(
955
global_config=sample_ignore_signatures,
956
branch_data_config=sample_always_signatures)
957
self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
958
self.assertEqual(config.SIGN_ALWAYS, my_config.signing_policy())
959
self.assertTrue(my_config.signature_needed())
961
def test_gpg_signing_command(self):
962
my_config = self.get_branch_config(
963
# branch data cannot set gpg_signing_command
964
branch_data_config="gpg_signing_command=pgp")
965
config_file = StringIO(sample_config_text.encode('utf-8'))
966
my_config._get_global_config()._get_parser(config_file)
967
self.assertEqual('gnome-gpg', my_config.gpg_signing_command())
969
def test_get_user_option_global(self):
970
branch = FakeBranch()
971
my_config = config.BranchConfig(branch)
972
config_file = StringIO(sample_config_text.encode('utf-8'))
973
(my_config._get_global_config()._get_parser(config_file))
974
self.assertEqual('something',
975
my_config.get_user_option('user_global_option'))
977
def test_post_commit_default(self):
978
branch = FakeBranch()
979
my_config = self.get_branch_config(sample_config_text, '/a/c',
980
sample_branches_text)
981
self.assertEqual(my_config.branch.base, '/a/c')
982
self.assertEqual('bzrlib.tests.test_config.post_commit',
983
my_config.post_commit())
984
my_config.set_user_option('post_commit', 'rmtree_root')
985
# post-commit is ignored when bresent in branch data
986
self.assertEqual('bzrlib.tests.test_config.post_commit',
987
my_config.post_commit())
988
my_config.set_user_option('post_commit', 'rmtree_root',
989
store=config.STORE_LOCATION)
990
self.assertEqual('rmtree_root', my_config.post_commit())
992
def test_config_precedence(self):
993
my_config = self.get_branch_config(global_config=precedence_global)
994
self.assertEqual(my_config.get_user_option('option'), 'global')
995
my_config = self.get_branch_config(global_config=precedence_global,
996
branch_data_config=precedence_branch)
997
self.assertEqual(my_config.get_user_option('option'), 'branch')
998
my_config = self.get_branch_config(global_config=precedence_global,
999
branch_data_config=precedence_branch,
1000
location_config=precedence_location)
1001
self.assertEqual(my_config.get_user_option('option'), 'recurse')
1002
my_config = self.get_branch_config(global_config=precedence_global,
1003
branch_data_config=precedence_branch,
1004
location_config=precedence_location,
1005
location='http://example.com/specific')
1006
self.assertEqual(my_config.get_user_option('option'), 'exact')
1009
class TestMailAddressExtraction(TestCase):
1011
def test_extract_email_address(self):
1012
self.assertEqual('jane@test.com',
1013
config.extract_email_address('Jane <jane@test.com>'))
1014
self.assertRaises(errors.NoEmailInUsername,
1015
config.extract_email_address, 'Jane Tester')
1018
class TestTreeConfig(TestCaseWithTransport):
1020
def test_get_value(self):
1021
"""Test that retreiving a value from a section is possible"""
1022
branch = self.make_branch('.')
1023
tree_config = config.TreeConfig(branch)
1024
tree_config.set_option('value', 'key', 'SECTION')
1025
tree_config.set_option('value2', 'key2')
1026
tree_config.set_option('value3-top', 'key3')
1027
tree_config.set_option('value3-section', 'key3', 'SECTION')
1028
value = tree_config.get_option('key', 'SECTION')
1029
self.assertEqual(value, 'value')
1030
value = tree_config.get_option('key2')
1031
self.assertEqual(value, 'value2')
1032
self.assertEqual(tree_config.get_option('non-existant'), None)
1033
value = tree_config.get_option('non-existant', 'SECTION')
1034
self.assertEqual(value, None)
1035
value = tree_config.get_option('non-existant', default='default')
1036
self.assertEqual(value, 'default')
1037
self.assertEqual(tree_config.get_option('key2', 'NOSECTION'), None)
1038
value = tree_config.get_option('key2', 'NOSECTION', default='default')
1039
self.assertEqual(value, 'default')
1040
value = tree_config.get_option('key3')
1041
self.assertEqual(value, 'value3-top')
1042
value = tree_config.get_option('key3', 'SECTION')
1043
self.assertEqual(value, 'value3-section')