15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
"""Tests for finding and reading the bzr config file[s]."""
18
# import system imports here
19
20
from cStringIO import StringIO
21
from textwrap import dedent
25
26
from testtools import matchers
27
#import bzrlib specific imports here
28
28
from bzrlib import (
116
116
def build_control_store(test):
117
117
build_backing_branch(test, 'branch')
118
b = bzrdir.BzrDir.open('branch')
118
b = controldir.ControlDir.open('branch')
119
119
return config.ControlStore(b)
120
120
config.test_store_builder_registry.register('control', build_control_store)
476
476
def test_constructs(self):
479
def test_no_default_editor(self):
482
self.applyDeprecated, deprecated_in((2, 4, 0)),
483
config.Config().get_editor)
485
479
def test_user_email(self):
486
480
my_config = InstrumentedConfig()
487
481
self.assertEqual('robert.collins@example.org', my_config.user_email())
577
571
def test_config_dir(self):
578
572
self.assertEqual(config.config_dir(), self.bzr_home)
574
def test_config_dir_is_unicode(self):
575
self.assertIsInstance(config.config_dir(), unicode)
580
577
def test_config_filename(self):
581
578
self.assertEqual(config.config_filename(),
582
579
self.bzr_home + '/bazaar.conf')
686
683
self.assertFileEqual(content, 'test.conf')
689
class TestIniConfigOptionExpansionDefaultValue(tests.TestCaseInTempDir):
690
"""What is the default value of expand for config options.
692
This is an opt-in beta feature used to evaluate whether or not option
693
references can appear in dangerous place raising exceptions, disapearing
694
(and as such corrupting data) or if it's safe to activate the option by
697
Note that these tests relies on config._expand_default_value being already
698
overwritten in the parent class setUp.
702
super(TestIniConfigOptionExpansionDefaultValue, self).setUp()
706
self.warnings.append(args[0] % args[1:])
707
self.overrideAttr(trace, 'warning', warning)
709
def get_config(self, expand):
710
c = config.GlobalConfig.from_string('bzr.config.expand=%s' % (expand,),
714
def assertExpandIs(self, expected):
715
actual = config._get_expand_default_value()
716
#self.config.get_user_option_as_bool('bzr.config.expand')
717
self.assertEquals(expected, actual)
719
def test_default_is_None(self):
720
self.assertEquals(None, config._expand_default_value)
722
def test_default_is_False_even_if_None(self):
723
self.config = self.get_config(None)
724
self.assertExpandIs(False)
726
def test_default_is_False_even_if_invalid(self):
727
self.config = self.get_config('<your choice>')
728
self.assertExpandIs(False)
730
# Huh ? My choice is False ? Thanks, always happy to hear that :D
731
# Wait, you've been warned !
732
self.assertLength(1, self.warnings)
734
'Value "<your choice>" is not a boolean for "bzr.config.expand"',
737
def test_default_is_True(self):
738
self.config = self.get_config(True)
739
self.assertExpandIs(True)
741
def test_default_is_False(self):
742
self.config = self.get_config(False)
743
self.assertExpandIs(False)
746
686
class TestIniConfigOptionExpansion(tests.TestCase):
747
687
"""Test option expansion from the IniConfig level.
1140
1080
def test_get_config(self):
1141
1081
"""The Branch.get_config method works properly"""
1142
b = bzrdir.BzrDir.create_standalone_workingtree('.').branch
1082
b = controldir.ControlDir.create_standalone_workingtree('.').branch
1143
1083
my_config = b.get_config()
1144
1084
self.assertIs(my_config.get_user_option('wacky'), None)
1145
1085
my_config.set_user_option('wacky', 'unlikely')
1194
1134
b = self.make_branch('!repo')
1195
1135
self.assertEqual('!repo', b.get_config().get_nickname())
1137
def test_autonick_uses_branch_name(self):
1138
b = self.make_branch('foo', name='bar')
1139
self.assertEqual('bar', b.get_config().get_nickname())
1197
1141
def test_warn_if_masked(self):
1199
1143
def warning(*args):
1239
1183
my_config = config.GlobalConfig()
1240
1184
self.assertEqual(None, my_config._get_user_id())
1242
def test_configured_editor(self):
1243
my_config = config.GlobalConfig.from_string(sample_config_text)
1244
editor = self.applyDeprecated(
1245
deprecated_in((2, 4, 0)), my_config.get_editor)
1246
self.assertEqual('vim', editor)
1248
1186
def test_signatures_always(self):
1249
1187
my_config = config.GlobalConfig.from_string(sample_always_signatures)
1250
1188
self.assertEqual(config.CHECK_NEVER,
1904
1842
location='http://example.com/specific')
1905
1843
self.assertEqual(my_config.get_user_option('option'), 'exact')
1907
def test_get_mail_client(self):
1908
config = self.get_branch_config()
1909
client = config.get_mail_client()
1910
self.assertIsInstance(client, mail_client.DefaultMail)
1913
config.set_user_option('mail_client', 'evolution')
1914
client = config.get_mail_client()
1915
self.assertIsInstance(client, mail_client.Evolution)
1917
config.set_user_option('mail_client', 'kmail')
1918
client = config.get_mail_client()
1919
self.assertIsInstance(client, mail_client.KMail)
1921
config.set_user_option('mail_client', 'mutt')
1922
client = config.get_mail_client()
1923
self.assertIsInstance(client, mail_client.Mutt)
1925
config.set_user_option('mail_client', 'thunderbird')
1926
client = config.get_mail_client()
1927
self.assertIsInstance(client, mail_client.Thunderbird)
1930
config.set_user_option('mail_client', 'default')
1931
client = config.get_mail_client()
1932
self.assertIsInstance(client, mail_client.DefaultMail)
1934
config.set_user_option('mail_client', 'editor')
1935
client = config.get_mail_client()
1936
self.assertIsInstance(client, mail_client.Editor)
1938
config.set_user_option('mail_client', 'mapi')
1939
client = config.get_mail_client()
1940
self.assertIsInstance(client, mail_client.MAPIClient)
1942
config.set_user_option('mail_client', 'xdg-email')
1943
client = config.get_mail_client()
1944
self.assertIsInstance(client, mail_client.XDGEmail)
1946
config.set_user_option('mail_client', 'firebird')
1947
self.assertRaises(errors.UnknownMailClient, config.get_mail_client)
1950
1846
class TestMailAddressExtraction(tests.TestCase):
2238
2134
self.assertGetHook(remote_branch._get_config(), 'file', 'branch')
2240
2136
def test_get_hook_remote_bzrdir(self):
2241
remote_bzrdir = bzrdir.BzrDir.open(self.get_url('tree'))
2137
remote_bzrdir = controldir.ControlDir.open(self.get_url('tree'))
2242
2138
conf = remote_bzrdir._get_config()
2243
2139
conf.set_option('remotedir', 'file')
2244
2140
self.assertGetHook(conf, 'file', 'remotedir')
2266
2162
def test_set_hook_remote_bzrdir(self):
2267
2163
remote_branch = branch.Branch.open(self.get_url('tree'))
2268
2164
self.addCleanup(remote_branch.lock_write().unlock)
2269
remote_bzrdir = bzrdir.BzrDir.open(self.get_url('tree'))
2165
remote_bzrdir = controldir.ControlDir.open(self.get_url('tree'))
2270
2166
self.assertSetHook(remote_bzrdir._get_config(), 'file', 'remotedir')
2272
2168
def assertLoadHook(self, expected_nb_calls, name, conf_class, *conf_args):
2289
2185
self.assertLoadHook(1, 'file', remote.RemoteBranchConfig, remote_branch)
2291
2187
def test_load_hook_remote_bzrdir(self):
2292
remote_bzrdir = bzrdir.BzrDir.open(self.get_url('tree'))
2188
remote_bzrdir = controldir.ControlDir.open(self.get_url('tree'))
2293
2189
# The config file doesn't exist, set an option to force its creation
2294
2190
conf = remote_bzrdir._get_config()
2295
2191
conf.set_option('remotedir', 'file')
2320
2216
def test_save_hook_remote_bzrdir(self):
2321
2217
remote_branch = branch.Branch.open(self.get_url('tree'))
2322
2218
self.addCleanup(remote_branch.lock_write().unlock)
2323
remote_bzrdir = bzrdir.BzrDir.open(self.get_url('tree'))
2219
remote_bzrdir = controldir.ControlDir.open(self.get_url('tree'))
2324
2220
self.assertSaveHook(remote_bzrdir._get_config())
2363
2259
opt = config.Option('foo', default=bar_not_unicode)
2364
2260
self.assertRaises(AssertionError, opt.get_default)
2262
def test_get_help_topic(self):
2263
opt = config.Option('foo')
2264
self.assertEquals('foo', opt.get_help_topic())
2367
2267
class TestOptionConverterMixin(object):
2578
2478
def test_help_is_set(self):
2579
2479
option_help = self.registry.get_help(self.option_name)
2580
self.assertNotEquals(None, option_help)
2581
2480
# Come on, think about the user, he really wants to know what the
2582
2481
# option is about
2583
2482
self.assertIsNot(None, option_help)
2961
2860
self.assertEquals(False, self.has_store(store))
2862
def test_mutable_section_shared(self):
2863
store = self.get_store(self)
2864
store._load_from_string('foo=bar\n')
2865
# FIXME: There should be a better way than relying on the test
2866
# parametrization to identify branch.conf -- vila 2011-0526
2867
if self.store_id in ('branch', 'remote_branch'):
2868
# branch stores requires write locked branches
2869
self.addCleanup(store.branch.lock_write().unlock)
2870
section1 = store.get_mutable_section(None)
2871
section2 = store.get_mutable_section(None)
2872
# If we get different sections, different callers won't share the
2874
self.assertIs(section1, section2)
2963
2876
def test_save_emptied_succeeds(self):
2964
2877
store = self.get_store(self)
2965
2878
store._load_from_string('foo=bar\n')
2879
# FIXME: There should be a better way than relying on the test
2880
# parametrization to identify branch.conf -- vila 2011-0526
2881
if self.store_id in ('branch', 'remote_branch'):
2882
# branch stores requires write locked branches
2883
self.addCleanup(store.branch.lock_write().unlock)
2966
2884
section = store.get_mutable_section(None)
2967
2885
section.remove('foo')
2990
2908
def test_set_option_in_empty_store(self):
2991
2909
store = self.get_store(self)
2910
# FIXME: There should be a better way than relying on the test
2911
# parametrization to identify branch.conf -- vila 2011-0526
2912
if self.store_id in ('branch', 'remote_branch'):
2913
# branch stores requires write locked branches
2914
self.addCleanup(store.branch.lock_write().unlock)
2992
2915
section = store.get_mutable_section(None)
2993
2916
section.set('foo', 'bar')
3000
2923
def test_set_option_in_default_section(self):
3001
2924
store = self.get_store(self)
3002
2925
store._load_from_string('')
2926
# FIXME: There should be a better way than relying on the test
2927
# parametrization to identify branch.conf -- vila 2011-0526
2928
if self.store_id in ('branch', 'remote_branch'):
2929
# branch stores requires write locked branches
2930
self.addCleanup(store.branch.lock_write().unlock)
3003
2931
section = store.get_mutable_section(None)
3004
2932
section.set('foo', 'bar')
3011
2939
def test_set_option_in_named_section(self):
3012
2940
store = self.get_store(self)
3013
2941
store._load_from_string('')
2942
# FIXME: There should be a better way than relying on the test
2943
# parametrization to identify branch.conf -- vila 2011-0526
2944
if self.store_id in ('branch', 'remote_branch'):
2945
# branch stores requires write locked branches
2946
self.addCleanup(store.branch.lock_write().unlock)
3014
2947
section = store.get_mutable_section('baz')
3015
2948
section.set('foo', 'bar')
3020
2953
self.assertSectionContent(('baz', {'foo': 'bar'}), sections[0])
3022
2955
def test_load_hook(self):
3023
# We first needs to ensure that the store exists
2956
# First, we need to ensure that the store exists
3024
2957
store = self.get_store(self)
2958
# FIXME: There should be a better way than relying on the test
2959
# parametrization to identify branch.conf -- vila 2011-0526
2960
if self.store_id in ('branch', 'remote_branch'):
2961
# branch stores requires write locked branches
2962
self.addCleanup(store.branch.lock_write().unlock)
3025
2963
section = store.get_mutable_section('baz')
3026
2964
section.set('foo', 'bar')
3043
2981
config.ConfigHooks.install_named_hook('save', hook, None)
3044
2982
self.assertLength(0, calls)
3045
2983
store = self.get_store(self)
2984
# FIXME: There should be a better way than relying on the test
2985
# parametrization to identify branch.conf -- vila 2011-0526
2986
if self.store_id in ('branch', 'remote_branch'):
2987
# branch stores requires write locked branches
2988
self.addCleanup(store.branch.lock_write().unlock)
3046
2989
section = store.get_mutable_section('baz')
3047
2990
section.set('foo', 'bar')
3475
3418
matcher = config.LocationMatcher(store, expected_url)
3476
3419
self.assertEquals(expected_location, matcher.location)
3421
def test_branch_name_colo(self):
3422
store = self.get_store(self)
3423
store._load_from_string(dedent("""\
3425
push_location=my{branchname}
3427
matcher = config.LocationMatcher(store, 'file:///,branch=example%3c')
3428
self.assertEqual('example<', matcher.branch_name)
3429
((_, section),) = matcher.get_sections()
3430
self.assertEqual('example<', section.locals['branchname'])
3432
def test_branch_name_basename(self):
3433
store = self.get_store(self)
3434
store._load_from_string(dedent("""\
3436
push_location=my{branchname}
3438
matcher = config.LocationMatcher(store, 'file:///parent/example%3c')
3439
self.assertEqual('example<', matcher.branch_name)
3440
((_, section),) = matcher.get_sections()
3441
self.assertEqual('example<', section.locals['branchname'])
3479
3444
class TestStartingPathMatcher(TestStore):
3640
3605
return config.MemoryStack(content)
3642
3607
def test_override_value_from_env(self):
3608
self.overrideEnv('FOO', None)
3643
3609
self.registry.register(
3644
3610
config.Option('foo', default='bar', override_from_env=['FOO']))
3645
3611
self.overrideEnv('FOO', 'quux')
3648
3614
self.assertEquals('quux', conf.get('foo'))
3650
3616
def test_first_override_value_from_env_wins(self):
3617
self.overrideEnv('NO_VALUE', None)
3618
self.overrideEnv('FOO', None)
3619
self.overrideEnv('BAZ', None)
3651
3620
self.registry.register(
3652
3621
config.Option('foo', default='bar',
3653
3622
override_from_env=['NO_VALUE', 'FOO', 'BAZ']))
3679
3648
self.assertEquals('bar', conf.get('foo'))
3651
class TestStackIterSections(tests.TestCase):
3653
def test_empty_stack(self):
3654
conf = config.Stack([])
3655
sections = list(conf.iter_sections())
3656
self.assertLength(0, sections)
3658
def test_empty_store(self):
3659
store = config.IniFileStore()
3660
store._load_from_string('')
3661
conf = config.Stack([store.get_sections])
3662
sections = list(conf.iter_sections())
3663
self.assertLength(0, sections)
3665
def test_simple_store(self):
3666
store = config.IniFileStore()
3667
store._load_from_string('foo=bar')
3668
conf = config.Stack([store.get_sections])
3669
tuples = list(conf.iter_sections())
3670
self.assertLength(1, tuples)
3671
(found_store, found_section) = tuples[0]
3672
self.assertIs(store, found_store)
3674
def test_two_stores(self):
3675
store1 = config.IniFileStore()
3676
store1._load_from_string('foo=bar')
3677
store2 = config.IniFileStore()
3678
store2._load_from_string('bar=qux')
3679
conf = config.Stack([store1.get_sections, store2.get_sections])
3680
tuples = list(conf.iter_sections())
3681
self.assertLength(2, tuples)
3682
self.assertIs(store1, tuples[0][0])
3683
self.assertIs(store2, tuples[1][0])
3682
3686
class TestStackWithTransport(tests.TestCaseWithTransport):
3684
3688
scenarios = [(key, {'get_stack': builder}) for key, builder
3874
3878
super(TestStackExpandOptions, self).setUp()
3875
3879
self.overrideAttr(config, 'option_registry', config.OptionRegistry())
3876
3880
self.registry = config.option_registry
3877
self.conf = build_branch_stack(self)
3881
store = config.TransportIniFileStore(self.get_transport(), 'foo.conf')
3882
self.conf = config.Stack([store.get_sections], store)
3879
3884
def assertExpansion(self, expected, string, env=None):
3880
3885
self.assertEquals(expected, self.conf.expand_options(string, env))
3966
self.registry.register(
3967
config.ListOption('list'))
3971
self.registry.register(config.ListOption('list'))
3972
# Register an intermediate option as a list to ensure no conversion
3973
# happen while expanding. Conversion should only occur for the original
3974
# option ('list' here).
3975
self.registry.register(config.ListOption('baz'))
3968
3976
self.assertEquals(['start', 'middle', 'end'],
3969
3977
self.conf.get('list', expand=True))
4339
4347
self.assertSectionNames(['ALIASES'], self.bazaar_config, 'ALIASES')
4350
class TestSharedStores(tests.TestCaseInTempDir):
4352
def test_bazaar_conf_shared(self):
4353
g1 = config.GlobalStack()
4354
g2 = config.GlobalStack()
4355
# The two stacks share the same store
4356
self.assertIs(g1.store, g2.store)
4342
4359
class TestAuthenticationConfigFile(tests.TestCase):
4343
4360
"""Test the authentication.conf file matching"""
4559
4576
port=99, path='/foo',
4561
4578
CREDENTIALS = {'name': 'name', 'user': 'user', 'password': 'password',
4562
'verify_certificates': False, 'scheme': 'scheme',
4563
'host': 'host', 'port': 99, 'path': '/foo',
4579
'verify_certificates': False, 'scheme': 'scheme',
4580
'host': 'host', 'port': 99, 'path': '/foo',
4564
4581
'realm': 'realm'}
4565
4582
self.assertEqual(CREDENTIALS, credentials)
4566
4583
credentials_from_disk = config.AuthenticationConfig().get_credentials(
4574
4591
self.assertIs(None, conf._get_config().get('name'))
4575
4592
credentials = conf.get_credentials(host='host', scheme='scheme')
4576
4593
CREDENTIALS = {'name': 'name2', 'user': 'user2', 'password':
4577
'password', 'verify_certificates': True,
4578
'scheme': 'scheme', 'host': 'host', 'port': None,
4594
'password', 'verify_certificates': True,
4595
'scheme': 'scheme', 'host': 'host', 'port': None,
4579
4596
'path': None, 'realm': None}
4580
4597
self.assertEqual(CREDENTIALS, credentials)
4833
4850
self.assertEquals('secret', decoded)
4853
class TestBase64CredentialStore(tests.TestCase):
4855
def test_decode_password(self):
4856
r = config.credential_store_registry
4857
plain_text = r.get_credential_store('base64')
4858
decoded = plain_text.decode_password(dict(password='c2VjcmV0'))
4859
self.assertEquals('secret', decoded)
4836
4862
# FIXME: Once we have a way to declare authentication to all test servers, we
4837
4863
# can implement generic tests.
4838
4864
# test_user_password_in_url
4867
4893
self.assertEquals((None, None), (realname, address))
4896
class TestDefaultMailDomain(tests.TestCaseInTempDir):
4897
"""Test retrieving default domain from mailname file"""
4899
def test_default_mail_domain_simple(self):
4900
f = file('simple', 'w')
4902
f.write("domainname.com\n")
4905
r = config._get_default_mail_domain('simple')
4906
self.assertEquals('domainname.com', r)
4908
def test_default_mail_domain_no_eol(self):
4909
f = file('no_eol', 'w')
4911
f.write("domainname.com")
4914
r = config._get_default_mail_domain('no_eol')
4915
self.assertEquals('domainname.com', r)
4917
def test_default_mail_domain_multiple_lines(self):
4918
f = file('multiple_lines', 'w')
4920
f.write("domainname.com\nsome other text\n")
4923
r = config._get_default_mail_domain('multiple_lines')
4924
self.assertEquals('domainname.com', r)
4870
4927
class EmailOptionTests(tests.TestCase):
4872
4929
def test_default_email_uses_BZR_EMAIL(self):
4889
4946
self.overrideEnv('BZR_EMAIL', None)
4890
4947
self.overrideEnv('EMAIL', 'jelmer@samba.org')
4891
4948
self.assertEquals('jelmer@debian.org', conf.get('email'))
4951
class MailClientOptionTests(tests.TestCase):
4953
def test_default(self):
4954
conf = config.MemoryStack('')
4955
client = conf.get('mail_client')
4956
self.assertIs(client, mail_client.DefaultMail)
4958
def test_evolution(self):
4959
conf = config.MemoryStack('mail_client=evolution')
4960
client = conf.get('mail_client')
4961
self.assertIs(client, mail_client.Evolution)
4963
def test_kmail(self):
4964
conf = config.MemoryStack('mail_client=kmail')
4965
client = conf.get('mail_client')
4966
self.assertIs(client, mail_client.KMail)
4968
def test_mutt(self):
4969
conf = config.MemoryStack('mail_client=mutt')
4970
client = conf.get('mail_client')
4971
self.assertIs(client, mail_client.Mutt)
4973
def test_thunderbird(self):
4974
conf = config.MemoryStack('mail_client=thunderbird')
4975
client = conf.get('mail_client')
4976
self.assertIs(client, mail_client.Thunderbird)
4978
def test_explicit_default(self):
4979
conf = config.MemoryStack('mail_client=default')
4980
client = conf.get('mail_client')
4981
self.assertIs(client, mail_client.DefaultMail)
4983
def test_editor(self):
4984
conf = config.MemoryStack('mail_client=editor')
4985
client = conf.get('mail_client')
4986
self.assertIs(client, mail_client.Editor)
4988
def test_mapi(self):
4989
conf = config.MemoryStack('mail_client=mapi')
4990
client = conf.get('mail_client')
4991
self.assertIs(client, mail_client.MAPIClient)
4993
def test_xdg_email(self):
4994
conf = config.MemoryStack('mail_client=xdg-email')
4995
client = conf.get('mail_client')
4996
self.assertIs(client, mail_client.XDGEmail)
4998
def test_unknown(self):
4999
conf = config.MemoryStack('mail_client=firebird')
5000
self.assertRaises(errors.ConfigOptionValueError, conf.get,