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
19
from cStringIO import StringIO
20
from textwrap import dedent
25
25
from testtools import matchers
27
#import bzrlib specific imports here
27
28
from bzrlib import (
37
registry as _mod_registry,
678
684
def test_saved_with_content(self):
679
685
content = 'foo = bar\n'
680
config.IniBasedConfig.from_string(content, file_name='./test.conf',
686
conf = config.IniBasedConfig.from_string(
687
content, file_name='./test.conf', save=True)
682
688
self.assertFileEqual(content, 'test.conf')
691
class TestIniConfigOptionExpansionDefaultValue(tests.TestCaseInTempDir):
692
"""What is the default value of expand for config options.
694
This is an opt-in beta feature used to evaluate whether or not option
695
references can appear in dangerous place raising exceptions, disapearing
696
(and as such corrupting data) or if it's safe to activate the option by
699
Note that these tests relies on config._expand_default_value being already
700
overwritten in the parent class setUp.
704
super(TestIniConfigOptionExpansionDefaultValue, self).setUp()
708
self.warnings.append(args[0] % args[1:])
709
self.overrideAttr(trace, 'warning', warning)
711
def get_config(self, expand):
712
c = config.GlobalConfig.from_string('bzr.config.expand=%s' % (expand,),
716
def assertExpandIs(self, expected):
717
actual = config._get_expand_default_value()
718
#self.config.get_user_option_as_bool('bzr.config.expand')
719
self.assertEquals(expected, actual)
721
def test_default_is_None(self):
722
self.assertEquals(None, config._expand_default_value)
724
def test_default_is_False_even_if_None(self):
725
self.config = self.get_config(None)
726
self.assertExpandIs(False)
728
def test_default_is_False_even_if_invalid(self):
729
self.config = self.get_config('<your choice>')
730
self.assertExpandIs(False)
732
# Huh ? My choice is False ? Thanks, always happy to hear that :D
733
# Wait, you've been warned !
734
self.assertLength(1, self.warnings)
736
'Value "<your choice>" is not a boolean for "bzr.config.expand"',
739
def test_default_is_True(self):
740
self.config = self.get_config(True)
741
self.assertExpandIs(True)
743
def test_default_is_False(self):
744
self.config = self.get_config(False)
745
self.assertExpandIs(False)
685
748
class TestIniConfigOptionExpansion(tests.TestCase):
686
749
"""Test option expansion from the IniConfig level.
782
845
# Nope, it's either a string or a list, and the list wins as soon as a
783
846
# ',' appears, so the string concatenation never occur.
784
self.assertEqual(['{foo', '}', '{', 'bar}'],
847
self.assertEquals(['{foo', '}', '{', 'bar}'],
785
848
conf.get_user_option('hidden', expand=True))
863
926
def test_simple_read_access(self):
864
self.assertEqual('1', self.config.get_user_option('one'))
927
self.assertEquals('1', self.config.get_user_option('one'))
866
929
def test_simple_write_access(self):
867
930
self.config.set_user_option('one', 'one')
868
self.assertEqual('one', self.config.get_user_option('one'))
931
self.assertEquals('one', self.config.get_user_option('one'))
870
933
def test_listen_to_the_last_speaker(self):
872
935
c2 = self.get_existing_config()
873
936
c1.set_user_option('one', 'ONE')
874
937
c2.set_user_option('two', 'TWO')
875
self.assertEqual('ONE', c1.get_user_option('one'))
876
self.assertEqual('TWO', c2.get_user_option('two'))
938
self.assertEquals('ONE', c1.get_user_option('one'))
939
self.assertEquals('TWO', c2.get_user_option('two'))
877
940
# The second update respect the first one
878
self.assertEqual('ONE', c2.get_user_option('one'))
941
self.assertEquals('ONE', c2.get_user_option('one'))
880
943
def test_last_speaker_wins(self):
881
944
# If the same config is not shared, the same variable modified twice
884
947
c2 = self.get_existing_config()
885
948
c1.set_user_option('one', 'c1')
886
949
c2.set_user_option('one', 'c2')
887
self.assertEqual('c2', c2._get_user_option('one'))
950
self.assertEquals('c2', c2._get_user_option('one'))
888
951
# The first modification is still available until another refresh
890
self.assertEqual('c1', c1._get_user_option('one'))
953
self.assertEquals('c1', c1._get_user_option('one'))
891
954
c1.set_user_option('two', 'done')
892
self.assertEqual('c2', c1._get_user_option('one'))
955
self.assertEquals('c2', c1._get_user_option('one'))
894
957
def test_writes_are_serialized(self):
920
983
self.assertTrue(c1._lock.is_held)
921
984
self.assertRaises(errors.LockContention,
922
985
c2.set_user_option, 'one', 'c2')
923
self.assertEqual('c1', c1.get_user_option('one'))
986
self.assertEquals('c1', c1.get_user_option('one'))
924
987
# Let the lock be released
925
988
after_writing.set()
926
989
writing_done.wait()
927
990
c2.set_user_option('one', 'c2')
928
self.assertEqual('c2', c2.get_user_option('one'))
991
self.assertEquals('c2', c2.get_user_option('one'))
930
993
def test_read_while_writing(self):
953
1016
# Ensure the thread is ready to write
954
1017
ready_to_write.wait()
955
1018
self.assertTrue(c1._lock.is_held)
956
self.assertEqual('c1', c1.get_user_option('one'))
1019
self.assertEquals('c1', c1.get_user_option('one'))
957
1020
# If we read during the write, we get the old value
958
1021
c2 = self.get_existing_config()
959
self.assertEqual('1', c2.get_user_option('one'))
1022
self.assertEquals('1', c2.get_user_option('one'))
960
1023
# Let the writing occur and ensure it occurred
961
1024
do_writing.set()
962
1025
writing_done.wait()
963
1026
# Now we get the updated value
964
1027
c3 = self.get_existing_config()
965
self.assertEqual('c1', c3.get_user_option('one'))
1028
self.assertEquals('c1', c3.get_user_option('one'))
968
1031
class TestGetUserOptionAs(TestIniConfig):
983
1046
self.overrideAttr(trace, 'warning', warning)
984
1047
msg = 'Value "%s" is not a boolean for "%s"'
985
1048
self.assertIs(None, get_bool('an_invalid_bool'))
986
self.assertEqual(msg % ('maybe', 'an_invalid_bool'), warnings[0])
1049
self.assertEquals(msg % ('maybe', 'an_invalid_bool'), warnings[0])
988
1051
self.assertIs(None, get_bool('not_defined_in_this_config'))
989
self.assertEqual([], warnings)
1052
self.assertEquals([], warnings)
991
1054
def test_get_user_option_as_list(self):
992
1055
conf, parser = self.make_config_parser("""
1187
1245
my_config = config.GlobalConfig()
1188
1246
self.assertEqual(None, my_config._get_user_id())
1248
def test_configured_editor(self):
1249
my_config = config.GlobalConfig.from_string(sample_config_text)
1250
editor = self.applyDeprecated(
1251
deprecated_in((2, 4, 0)), my_config.get_editor)
1252
self.assertEqual('vim', editor)
1190
1254
def test_signatures_always(self):
1191
1255
my_config = config.GlobalConfig.from_string(sample_always_signatures)
1192
1256
self.assertEqual(config.CHECK_NEVER,
1668
1730
if location_config is None:
1669
1731
location_config = sample_branches_text
1671
config.GlobalConfig.from_string(global_config, save=True)
1672
config.LocationConfig.from_string(location_config, my_branch.base,
1733
my_global_config = config.GlobalConfig.from_string(global_config,
1735
my_location_config = config.LocationConfig.from_string(
1736
location_config, my_branch.base, save=True)
1674
1737
my_config = config.BranchConfig(my_branch)
1675
1738
self.my_config = my_config
1676
1739
self.my_location_config = my_config._get_location_config()
1741
1804
location_config=None, branch_data_config=None):
1742
1805
my_branch = FakeBranch(location)
1743
1806
if global_config is not None:
1744
config.GlobalConfig.from_string(global_config, save=True)
1807
my_global_config = config.GlobalConfig.from_string(global_config,
1745
1809
if location_config is not None:
1746
config.LocationConfig.from_string(location_config, my_branch.base,
1810
my_location_config = config.LocationConfig.from_string(
1811
location_config, my_branch.base, save=True)
1748
1812
my_config = config.BranchConfig(my_branch)
1749
1813
if branch_data_config is not None:
1750
1814
my_config.branch.control_files.files['branch.conf'] = \
1846
1910
location='http://example.com/specific')
1847
1911
self.assertEqual(my_config.get_user_option('option'), 'exact')
1913
def test_get_mail_client(self):
1914
config = self.get_branch_config()
1915
client = config.get_mail_client()
1916
self.assertIsInstance(client, mail_client.DefaultMail)
1919
config.set_user_option('mail_client', 'evolution')
1920
client = config.get_mail_client()
1921
self.assertIsInstance(client, mail_client.Evolution)
1923
config.set_user_option('mail_client', 'kmail')
1924
client = config.get_mail_client()
1925
self.assertIsInstance(client, mail_client.KMail)
1927
config.set_user_option('mail_client', 'mutt')
1928
client = config.get_mail_client()
1929
self.assertIsInstance(client, mail_client.Mutt)
1931
config.set_user_option('mail_client', 'thunderbird')
1932
client = config.get_mail_client()
1933
self.assertIsInstance(client, mail_client.Thunderbird)
1936
config.set_user_option('mail_client', 'default')
1937
client = config.get_mail_client()
1938
self.assertIsInstance(client, mail_client.DefaultMail)
1940
config.set_user_option('mail_client', 'editor')
1941
client = config.get_mail_client()
1942
self.assertIsInstance(client, mail_client.Editor)
1944
config.set_user_option('mail_client', 'mapi')
1945
client = config.get_mail_client()
1946
self.assertIsInstance(client, mail_client.MAPIClient)
1948
config.set_user_option('mail_client', 'xdg-email')
1949
client = config.get_mail_client()
1950
self.assertIsInstance(client, mail_client.XDGEmail)
1952
config.set_user_option('mail_client', 'firebird')
1953
self.assertRaises(errors.UnknownMailClient, config.get_mail_client)
1850
1956
class TestMailAddressExtraction(tests.TestCase):
1998
2104
config.OldConfigHooks.uninstall_named_hook, 'get', None)
1999
2105
self.assertLength(0, calls)
2000
2106
actual_value = conf.get_user_option(name)
2001
self.assertEqual(value, actual_value)
2107
self.assertEquals(value, actual_value)
2002
2108
self.assertLength(1, calls)
2003
self.assertEqual((conf, name, value), calls[0])
2109
self.assertEquals((conf, name, value), calls[0])
2005
2111
def test_get_hook_bazaar(self):
2006
2112
self.assertGetHook(self.bazaar_config, 'file', 'bazaar')
2129
2235
config.OldConfigHooks.uninstall_named_hook, 'get', None)
2130
2236
self.assertLength(0, calls)
2131
2237
actual_value = conf.get_option(name)
2132
self.assertEqual(value, actual_value)
2238
self.assertEquals(value, actual_value)
2133
2239
self.assertLength(1, calls)
2134
self.assertEqual((conf, name, value), calls[0])
2240
self.assertEquals((conf, name, value), calls[0])
2136
2242
def test_get_hook_remote_branch(self):
2137
2243
remote_branch = branch.Branch.open(self.get_url('tree'))
2138
2244
self.assertGetHook(remote_branch._get_config(), 'file', 'branch')
2140
2246
def test_get_hook_remote_bzrdir(self):
2141
remote_bzrdir = controldir.ControlDir.open(self.get_url('tree'))
2247
remote_bzrdir = bzrdir.BzrDir.open(self.get_url('tree'))
2142
2248
conf = remote_bzrdir._get_config()
2143
2249
conf.set_option('remotedir', 'file')
2144
2250
self.assertGetHook(conf, 'file', 'remotedir')
2220
2326
def test_save_hook_remote_bzrdir(self):
2221
2327
remote_branch = branch.Branch.open(self.get_url('tree'))
2222
2328
self.addCleanup(remote_branch.lock_write().unlock)
2223
remote_bzrdir = controldir.ControlDir.open(self.get_url('tree'))
2329
remote_bzrdir = bzrdir.BzrDir.open(self.get_url('tree'))
2224
2330
self.assertSaveHook(remote_bzrdir._get_config())
2227
class TestOptionNames(tests.TestCase):
2229
def is_valid(self, name):
2230
return config._option_ref_re.match('{%s}' % name) is not None
2232
def test_valid_names(self):
2233
self.assertTrue(self.is_valid('foo'))
2234
self.assertTrue(self.is_valid('foo.bar'))
2235
self.assertTrue(self.is_valid('f1'))
2236
self.assertTrue(self.is_valid('_'))
2237
self.assertTrue(self.is_valid('__bar__'))
2238
self.assertTrue(self.is_valid('a_'))
2239
self.assertTrue(self.is_valid('a1'))
2240
# Don't break bzr-svn for no good reason
2241
self.assertTrue(self.is_valid('guessed-layout'))
2243
def test_invalid_names(self):
2244
self.assertFalse(self.is_valid(' foo'))
2245
self.assertFalse(self.is_valid('foo '))
2246
self.assertFalse(self.is_valid('1'))
2247
self.assertFalse(self.is_valid('1,2'))
2248
self.assertFalse(self.is_valid('foo$'))
2249
self.assertFalse(self.is_valid('!foo'))
2250
self.assertFalse(self.is_valid('foo.'))
2251
self.assertFalse(self.is_valid('foo..bar'))
2252
self.assertFalse(self.is_valid('{}'))
2253
self.assertFalse(self.is_valid('{a}'))
2254
self.assertFalse(self.is_valid('a\n'))
2255
self.assertFalse(self.is_valid('-'))
2256
self.assertFalse(self.is_valid('-a'))
2257
self.assertFalse(self.is_valid('a-'))
2258
self.assertFalse(self.is_valid('a--a'))
2260
def assertSingleGroup(self, reference):
2261
# the regexp is used with split and as such should match the reference
2262
# *only*, if more groups needs to be defined, (?:...) should be used.
2263
m = config._option_ref_re.match('{a}')
2264
self.assertLength(1, m.groups())
2266
def test_valid_references(self):
2267
self.assertSingleGroup('{a}')
2268
self.assertSingleGroup('{{a}}')
2271
2333
class TestOption(tests.TestCase):
2273
2335
def test_default_value(self):
2274
2336
opt = config.Option('foo', default='bar')
2275
self.assertEqual('bar', opt.get_default())
2337
self.assertEquals('bar', opt.get_default())
2277
2339
def test_callable_default_value(self):
2278
2340
def bar_as_unicode():
2280
2342
opt = config.Option('foo', default=bar_as_unicode)
2281
self.assertEqual('bar', opt.get_default())
2343
self.assertEquals('bar', opt.get_default())
2283
2345
def test_default_value_from_env(self):
2284
2346
opt = config.Option('foo', default='bar', default_from_env=['FOO'])
2285
2347
self.overrideEnv('FOO', 'quux')
2286
2348
# Env variable provides a default taking over the option one
2287
self.assertEqual('quux', opt.get_default())
2349
self.assertEquals('quux', opt.get_default())
2289
2351
def test_first_default_value_from_env_wins(self):
2290
2352
opt = config.Option('foo', default='bar',
2310
2372
def test_get_help_topic(self):
2311
2373
opt = config.Option('foo')
2312
self.assertEqual('foo', opt.get_help_topic())
2315
class TestOptionConverter(tests.TestCase):
2374
self.assertEquals('foo', opt.get_help_topic())
2377
class TestOptionConverterMixin(object):
2317
2379
def assertConverted(self, expected, opt, value):
2318
self.assertEqual(expected, opt.convert_from_unicode(None, value))
2380
self.assertEquals(expected, opt.convert_from_unicode(None, value))
2320
def assertCallsWarning(self, opt, value):
2382
def assertWarns(self, opt, value):
2323
2384
def warning(*args):
2324
2385
warnings.append(args[0] % args[1:])
2325
2386
self.overrideAttr(trace, 'warning', warning)
2326
self.assertEqual(None, opt.convert_from_unicode(None, value))
2387
self.assertEquals(None, opt.convert_from_unicode(None, value))
2327
2388
self.assertLength(1, warnings)
2329
2390
'Value "%s" is not valid for "%s"' % (value, opt.name),
2332
def assertCallsError(self, opt, value):
2393
def assertErrors(self, opt, value):
2333
2394
self.assertRaises(errors.ConfigOptionValueError,
2334
2395
opt.convert_from_unicode, None, value)
2336
2397
def assertConvertInvalid(self, opt, invalid_value):
2337
2398
opt.invalid = None
2338
self.assertEqual(None, opt.convert_from_unicode(None, invalid_value))
2399
self.assertEquals(None, opt.convert_from_unicode(None, invalid_value))
2339
2400
opt.invalid = 'warning'
2340
self.assertCallsWarning(opt, invalid_value)
2401
self.assertWarns(opt, invalid_value)
2341
2402
opt.invalid = 'error'
2342
self.assertCallsError(opt, invalid_value)
2345
class TestOptionWithBooleanConverter(TestOptionConverter):
2403
self.assertErrors(opt, invalid_value)
2406
class TestOptionWithBooleanConverter(tests.TestCase, TestOptionConverterMixin):
2347
2408
def get_option(self):
2348
2409
return config.Option('foo', help='A boolean.',
2389
2450
def test_convert_invalid(self):
2390
2451
opt = self.get_option()
2391
2452
self.assertConvertInvalid(opt, u'not-a-unit')
2392
self.assertConvertInvalid(opt, u'Gb') # Forgot the value
2393
self.assertConvertInvalid(opt, u'1b') # Forgot the unit
2453
self.assertConvertInvalid(opt, u'Gb') # Forgot the int
2454
self.assertConvertInvalid(opt, u'1b') # Forgot the unit
2394
2455
self.assertConvertInvalid(opt, u'1GG')
2395
2456
self.assertConvertInvalid(opt, u'1Mbb')
2396
2457
self.assertConvertInvalid(opt, u'1MM')
2430
2491
self.assertConverted([u'bar'], opt, u'bar')
2433
class TestRegistryOption(TestOptionConverter):
2435
def get_option(self, registry):
2436
return config.RegistryOption('foo', registry,
2437
help='A registry option.')
2439
def test_convert_invalid(self):
2440
registry = _mod_registry.Registry()
2441
opt = self.get_option(registry)
2442
self.assertConvertInvalid(opt, [1])
2443
self.assertConvertInvalid(opt, u"notregistered")
2445
def test_convert_valid(self):
2446
registry = _mod_registry.Registry()
2447
registry.register("someval", 1234)
2448
opt = self.get_option(registry)
2449
# Using a bare str() just in case
2450
self.assertConverted(1234, opt, "someval")
2451
self.assertConverted(1234, opt, u'someval')
2452
self.assertConverted(None, opt, None)
2454
def test_help(self):
2455
registry = _mod_registry.Registry()
2456
registry.register("someval", 1234, help="some option")
2457
registry.register("dunno", 1234, help="some other option")
2458
opt = self.get_option(registry)
2460
'A registry option.\n'
2462
'The following values are supported:\n'
2463
' dunno - some other option\n'
2464
' someval - some option\n',
2467
def test_get_help_text(self):
2468
registry = _mod_registry.Registry()
2469
registry.register("someval", 1234, help="some option")
2470
registry.register("dunno", 1234, help="some other option")
2471
opt = self.get_option(registry)
2473
'A registry option.\n'
2475
'The following values are supported:\n'
2476
' dunno - some other option\n'
2477
' someval - some option\n',
2478
opt.get_help_text())
2481
2494
class TestOptionRegistry(tests.TestCase):
2483
2496
def setUp(self):
2494
2507
def test_registered_help(self):
2495
2508
opt = config.Option('foo', help='A simple option')
2496
2509
self.registry.register(opt)
2497
self.assertEqual('A simple option', self.registry.get_help('foo'))
2499
def test_dont_register_illegal_name(self):
2500
self.assertRaises(errors.IllegalOptionName,
2501
self.registry.register, config.Option(' foo'))
2502
self.assertRaises(errors.IllegalOptionName,
2503
self.registry.register, config.Option('bar,'))
2510
self.assertEquals('A simple option', self.registry.get_help('foo'))
2505
2512
lazy_option = config.Option('lazy_foo', help='Lazy help')
2512
2519
def test_registered_lazy_help(self):
2513
2520
self.registry.register_lazy('lazy_foo', self.__module__,
2514
2521
'TestOptionRegistry.lazy_option')
2515
self.assertEqual('Lazy help', self.registry.get_help('lazy_foo'))
2517
def test_dont_lazy_register_illegal_name(self):
2518
# This is where the root cause of http://pad.lv/1235099 is better
2519
# understood: 'register_lazy' doc string mentions that key should match
2520
# the option name which indirectly requires that the option name is a
2521
# valid python identifier. We violate that rule here (using a key that
2522
# doesn't match the option name) to test the option name checking.
2523
self.assertRaises(errors.IllegalOptionName,
2524
self.registry.register_lazy, ' foo', self.__module__,
2525
'TestOptionRegistry.lazy_option')
2526
self.assertRaises(errors.IllegalOptionName,
2527
self.registry.register_lazy, '1,2', self.__module__,
2528
'TestOptionRegistry.lazy_option')
2522
self.assertEquals('Lazy help', self.registry.get_help('lazy_foo'))
2531
2525
class TestRegisteredOptions(tests.TestCase):
2541
2535
def test_proper_name(self):
2542
2536
# An option should be registered under its own name, this can't be
2543
2537
# checked at registration time for the lazy ones.
2544
self.assertEqual(self.option_name, self.option.name)
2538
self.assertEquals(self.option_name, self.option.name)
2546
2540
def test_help_is_set(self):
2547
2541
option_help = self.registry.get_help(self.option_name)
2542
self.assertNotEquals(None, option_help)
2548
2543
# Come on, think about the user, he really wants to know what the
2549
2544
# option is about
2550
2545
self.assertIsNot(None, option_help)
2551
self.assertNotEqual('', option_help)
2546
self.assertNotEquals('', option_help)
2554
2549
class TestSection(tests.TestCase):
2559
2554
def test_get_a_value(self):
2560
2555
a_dict = dict(foo='bar')
2561
2556
section = config.Section('myID', a_dict)
2562
self.assertEqual('bar', section.get('foo'))
2557
self.assertEquals('bar', section.get('foo'))
2564
2559
def test_get_unknown_option(self):
2565
2560
a_dict = dict()
2566
2561
section = config.Section(None, a_dict)
2567
self.assertEqual('out of thin air',
2562
self.assertEquals('out of thin air',
2568
2563
section.get('foo', 'out of thin air'))
2570
2565
def test_options_is_shared(self):
2584
2579
a_dict = dict(foo='bar')
2585
2580
section = self.get_section(a_dict)
2586
2581
section.set('foo', 'new_value')
2587
self.assertEqual('new_value', section.get('foo'))
2582
self.assertEquals('new_value', section.get('foo'))
2588
2583
# The change appears in the shared section
2589
self.assertEqual('new_value', a_dict.get('foo'))
2584
self.assertEquals('new_value', a_dict.get('foo'))
2590
2585
# We keep track of the change
2591
2586
self.assertTrue('foo' in section.orig)
2592
self.assertEqual('bar', section.orig.get('foo'))
2587
self.assertEquals('bar', section.orig.get('foo'))
2594
2589
def test_set_preserve_original_once(self):
2595
2590
a_dict = dict(foo='bar')
2598
2593
section.set('foo', 'second_value')
2599
2594
# We keep track of the original value
2600
2595
self.assertTrue('foo' in section.orig)
2601
self.assertEqual('bar', section.orig.get('foo'))
2596
self.assertEquals('bar', section.orig.get('foo'))
2603
2598
def test_remove(self):
2604
2599
a_dict = dict(foo='bar')
2605
2600
section = self.get_section(a_dict)
2606
2601
section.remove('foo')
2607
2602
# We get None for unknown options via the default value
2608
self.assertEqual(None, section.get('foo'))
2603
self.assertEquals(None, section.get('foo'))
2609
2604
# Or we just get the default value
2610
self.assertEqual('unknown', section.get('foo', 'unknown'))
2605
self.assertEquals('unknown', section.get('foo', 'unknown'))
2611
2606
self.assertFalse('foo' in section.options)
2612
2607
# We keep track of the deletion
2613
2608
self.assertTrue('foo' in section.orig)
2614
self.assertEqual('bar', section.orig.get('foo'))
2609
self.assertEquals('bar', section.orig.get('foo'))
2616
2611
def test_remove_new_option(self):
2617
2612
a_dict = dict()
2664
2659
def test_multiple_overrides(self):
2665
2660
self.store._from_cmdline(['a=b', 'x=y'])
2666
2661
section = self.get_section()
2667
self.assertEqual('b', section.get('a'))
2668
self.assertEqual('y', section.get('x'))
2662
self.assertEquals('b', section.get('a'))
2663
self.assertEquals('y', section.get('x'))
2670
2665
def test_wrong_syntax(self):
2671
2666
self.assertRaises(errors.BzrCommandError,
2705
2700
def test_building_delays_load(self):
2706
2701
store = self.get_store(self)
2707
self.assertEqual(False, store.is_loaded())
2702
self.assertEquals(False, store.is_loaded())
2708
2703
store._load_from_string('')
2709
self.assertEqual(True, store.is_loaded())
2704
self.assertEquals(True, store.is_loaded())
2711
2706
def test_get_no_sections_for_empty(self):
2712
2707
store = self.get_store(self)
2713
2708
store._load_from_string('')
2714
self.assertEqual([], list(store.get_sections()))
2709
self.assertEquals([], list(store.get_sections()))
2716
2711
def test_get_default_section(self):
2717
2712
store = self.get_store(self)
2797
2792
value = conf.get('a_section')
2798
2793
# Urgh, despite 'conf' asking for the no-name section, we get the
2799
2794
# content of another section as a dict o_O
2800
self.assertEqual({'a': '1'}, value)
2795
self.assertEquals({'a': '1'}, value)
2801
2796
unquoted = conf.store.unquote(value)
2802
2797
# Which cannot be unquoted but shouldn't crash either (the use cases
2803
2798
# are getting the value or displaying it. In the later case, '%s' will
2805
self.assertEqual({'a': '1'}, unquoted)
2806
self.assertEqual("{u'a': u'1'}", '%s' % (unquoted,))
2800
self.assertEquals({'a': '1'}, unquoted)
2801
self.assertEquals("{u'a': u'1'}", '%s' % (unquoted,))
2809
2804
class TestIniFileStoreContent(tests.TestCaseWithTransport):
2925
2920
'branch.conf is *always* created when a branch is initialized')
2926
2921
store = self.get_store(self)
2928
self.assertEqual(False, self.has_store(store))
2930
def test_mutable_section_shared(self):
2931
store = self.get_store(self)
2932
store._load_from_string('foo=bar\n')
2933
# FIXME: There should be a better way than relying on the test
2934
# parametrization to identify branch.conf -- vila 2011-0526
2935
if self.store_id in ('branch', 'remote_branch'):
2936
# branch stores requires write locked branches
2937
self.addCleanup(store.branch.lock_write().unlock)
2938
section1 = store.get_mutable_section(None)
2939
section2 = store.get_mutable_section(None)
2940
# If we get different sections, different callers won't share the
2942
self.assertIs(section1, section2)
2923
self.assertEquals(False, self.has_store(store))
2944
2925
def test_save_emptied_succeeds(self):
2945
2926
store = self.get_store(self)
2946
2927
store._load_from_string('foo=bar\n')
2947
# FIXME: There should be a better way than relying on the test
2948
# parametrization to identify branch.conf -- vila 2011-0526
2949
if self.store_id in ('branch', 'remote_branch'):
2950
# branch stores requires write locked branches
2951
self.addCleanup(store.branch.lock_write().unlock)
2952
2928
section = store.get_mutable_section(None)
2953
2929
section.remove('foo')
2955
self.assertEqual(True, self.has_store(store))
2931
self.assertEquals(True, self.has_store(store))
2956
2932
modified_store = self.get_store(self)
2957
2933
sections = list(modified_store.get_sections())
2958
2934
self.assertLength(0, sections)
2965
2941
'branch.conf is *always* created when a branch is initialized')
2966
2942
store = self.get_store(self)
2967
2943
store._load_from_string('foo=bar\n')
2968
self.assertEqual(False, self.has_store(store))
2944
self.assertEquals(False, self.has_store(store))
2970
self.assertEqual(True, self.has_store(store))
2946
self.assertEquals(True, self.has_store(store))
2971
2947
modified_store = self.get_store(self)
2972
2948
sections = list(modified_store.get_sections())
2973
2949
self.assertLength(1, sections)
2991
2962
def test_set_option_in_default_section(self):
2992
2963
store = self.get_store(self)
2993
2964
store._load_from_string('')
2994
# FIXME: There should be a better way than relying on the test
2995
# parametrization to identify branch.conf -- vila 2011-0526
2996
if self.store_id in ('branch', 'remote_branch'):
2997
# branch stores requires write locked branches
2998
self.addCleanup(store.branch.lock_write().unlock)
2999
2965
section = store.get_mutable_section(None)
3000
2966
section.set('foo', 'bar')
3007
2973
def test_set_option_in_named_section(self):
3008
2974
store = self.get_store(self)
3009
2975
store._load_from_string('')
3010
# FIXME: There should be a better way than relying on the test
3011
# parametrization to identify branch.conf -- vila 2011-0526
3012
if self.store_id in ('branch', 'remote_branch'):
3013
# branch stores requires write locked branches
3014
self.addCleanup(store.branch.lock_write().unlock)
3015
2976
section = store.get_mutable_section('baz')
3016
2977
section.set('foo', 'bar')
3021
2982
self.assertSectionContent(('baz', {'foo': 'bar'}), sections[0])
3023
2984
def test_load_hook(self):
3024
# First, we need to ensure that the store exists
2985
# We first needs to ensure that the store exists
3025
2986
store = self.get_store(self)
3026
# FIXME: There should be a better way than relying on the test
3027
# parametrization to identify branch.conf -- vila 2011-0526
3028
if self.store_id in ('branch', 'remote_branch'):
3029
# branch stores requires write locked branches
3030
self.addCleanup(store.branch.lock_write().unlock)
3031
2987
section = store.get_mutable_section('baz')
3032
2988
section.set('foo', 'bar')
3049
3005
config.ConfigHooks.install_named_hook('save', hook, None)
3050
3006
self.assertLength(0, calls)
3051
3007
store = self.get_store(self)
3052
# FIXME: There should be a better way than relying on the test
3053
# parametrization to identify branch.conf -- vila 2011-0526
3054
if self.store_id in ('branch', 'remote_branch'):
3055
# branch stores requires write locked branches
3056
self.addCleanup(store.branch.lock_write().unlock)
3057
3008
section = store.get_mutable_section('baz')
3058
3009
section.set('foo', 'bar')
3060
3011
self.assertLength(1, calls)
3061
self.assertEqual((store,), calls[0])
3012
self.assertEquals((store,), calls[0])
3063
3014
def test_set_mark_dirty(self):
3064
3015
stack = config.MemoryStack('')
3112
3063
s2.set('baz', 'quux')
3113
3064
s1.store.save()
3114
3065
# Changes don't propagate magically
3115
self.assertEqual(None, s1.get('baz'))
3066
self.assertEquals(None, s1.get('baz'))
3116
3067
s2.store.save_changes()
3117
self.assertEqual('quux', s2.get('baz'))
3068
self.assertEquals('quux', s2.get('baz'))
3118
3069
# Changes are acquired when saving
3119
self.assertEqual('bar', s2.get('foo'))
3070
self.assertEquals('bar', s2.get('foo'))
3120
3071
# Since there is no overlap, no warnings are emitted
3121
3072
self.assertLength(0, self.warnings)
3184
3135
def test_invalid_content(self):
3185
3136
store = config.TransportIniFileStore(self.get_transport(), 'foo.conf')
3186
self.assertEqual(False, store.is_loaded())
3137
self.assertEquals(False, store.is_loaded())
3187
3138
exc = self.assertRaises(
3188
3139
errors.ParseConfigError, store._load_from_string,
3189
3140
'this is invalid !')
3190
3141
self.assertEndsWith(exc.filename, 'foo.conf')
3191
3142
# And the load failed
3192
self.assertEqual(False, store.is_loaded())
3143
self.assertEquals(False, store.is_loaded())
3194
3145
def test_get_embedded_sections(self):
3195
3146
# A more complicated example (which also shows that section names and
3262
3213
self.stack.store.save()
3264
3215
def test_simple_read_access(self):
3265
self.assertEqual('1', self.stack.get('one'))
3216
self.assertEquals('1', self.stack.get('one'))
3267
3218
def test_simple_write_access(self):
3268
3219
self.stack.set('one', 'one')
3269
self.assertEqual('one', self.stack.get('one'))
3220
self.assertEquals('one', self.stack.get('one'))
3271
3222
def test_listen_to_the_last_speaker(self):
3272
3223
c1 = self.stack
3273
3224
c2 = self.get_stack(self)
3274
3225
c1.set('one', 'ONE')
3275
3226
c2.set('two', 'TWO')
3276
self.assertEqual('ONE', c1.get('one'))
3277
self.assertEqual('TWO', c2.get('two'))
3227
self.assertEquals('ONE', c1.get('one'))
3228
self.assertEquals('TWO', c2.get('two'))
3278
3229
# The second update respect the first one
3279
self.assertEqual('ONE', c2.get('one'))
3230
self.assertEquals('ONE', c2.get('one'))
3281
3232
def test_last_speaker_wins(self):
3282
3233
# If the same config is not shared, the same variable modified twice
3285
3236
c2 = self.get_stack(self)
3286
3237
c1.set('one', 'c1')
3287
3238
c2.set('one', 'c2')
3288
self.assertEqual('c2', c2.get('one'))
3239
self.assertEquals('c2', c2.get('one'))
3289
3240
# The first modification is still available until another refresh
3291
self.assertEqual('c1', c1.get('one'))
3242
self.assertEquals('c1', c1.get('one'))
3292
3243
c1.set('two', 'done')
3293
self.assertEqual('c2', c1.get('one'))
3244
self.assertEquals('c2', c1.get('one'))
3295
3246
def test_writes_are_serialized(self):
3296
3247
c1 = self.stack
3354
3305
# Ensure the thread is ready to write
3355
3306
ready_to_write.wait()
3356
self.assertEqual('c1', c1.get('one'))
3307
self.assertEquals('c1', c1.get('one'))
3357
3308
# If we read during the write, we get the old value
3358
3309
c2 = self.get_stack(self)
3359
self.assertEqual('1', c2.get('one'))
3310
self.assertEquals('1', c2.get('one'))
3360
3311
# Let the writing occur and ensure it occurred
3361
3312
do_writing.set()
3362
3313
writing_done.wait()
3363
3314
# Now we get the updated value
3364
3315
c3 = self.get_stack(self)
3365
self.assertEqual('c1', c3.get('one'))
3316
self.assertEquals('c1', c3.get('one'))
3367
3318
# FIXME: It may be worth looking into removing the lock dir when it's not
3368
3319
# needed anymore and look at possible fallouts for concurrent lockers. This
3384
3335
store = self.get_store(self)
3385
3336
store._load_from_string('')
3386
3337
matcher = self.matcher(store, '/bar')
3387
self.assertEqual([], list(matcher.get_sections()))
3338
self.assertEquals([], list(matcher.get_sections()))
3389
3340
def test_build_doesnt_load_store(self):
3390
3341
store = self.get_store(self)
3391
self.matcher(store, '/bar')
3342
matcher = self.matcher(store, '/bar')
3392
3343
self.assertFalse(store.is_loaded())
3401
3352
def test_simple_option(self):
3402
3353
section = self.get_section({'foo': 'bar'}, '')
3403
self.assertEqual('bar', section.get('foo'))
3354
self.assertEquals('bar', section.get('foo'))
3405
3356
def test_option_with_extra_path(self):
3406
3357
section = self.get_section({'foo': 'bar', 'foo:policy': 'appendpath'},
3408
self.assertEqual('bar/baz', section.get('foo'))
3359
self.assertEquals('bar/baz', section.get('foo'))
3410
3361
def test_invalid_policy(self):
3411
3362
section = self.get_section({'foo': 'bar', 'foo:policy': 'die'},
3413
3364
# invalid policies are ignored
3414
self.assertEqual('bar', section.get('foo'))
3365
self.assertEquals('bar', section.get('foo'))
3417
3368
class TestLocationMatcher(TestStore):
3436
3387
section=/quux/quux
3438
self.assertEqual(['/foo', '/foo/baz', '/foo/bar', '/foo/bar/baz',
3389
self.assertEquals(['/foo', '/foo/baz', '/foo/bar', '/foo/bar/baz',
3440
3391
[section.id for _, section in store.get_sections()])
3441
3392
matcher = config.LocationMatcher(store, '/foo/bar/quux')
3442
3393
sections = [section for _, section in matcher.get_sections()]
3443
self.assertEqual(['/foo/bar', '/foo'],
3394
self.assertEquals(['/foo/bar', '/foo'],
3444
3395
[section.id for section in sections])
3445
self.assertEqual(['quux', 'bar/quux'],
3396
self.assertEquals(['quux', 'bar/quux'],
3446
3397
[section.extra_path for section in sections])
3448
3399
def test_more_specific_sections_first(self):
3454
3405
section=/foo/bar
3456
self.assertEqual(['/foo', '/foo/bar'],
3407
self.assertEquals(['/foo', '/foo/bar'],
3457
3408
[section.id for _, section in store.get_sections()])
3458
3409
matcher = config.LocationMatcher(store, '/foo/bar/baz')
3459
3410
sections = [section for _, section in matcher.get_sections()]
3460
self.assertEqual(['/foo/bar', '/foo'],
3411
self.assertEquals(['/foo/bar', '/foo'],
3461
3412
[section.id for section in sections])
3462
self.assertEqual(['baz', 'bar/baz'],
3413
self.assertEquals(['baz', 'bar/baz'],
3463
3414
[section.extra_path for section in sections])
3465
3416
def test_appendpath_in_no_name_section(self):
3484
3435
expected_url = 'file:///dir/subdir'
3485
3436
expected_location = '/dir/subdir'
3486
3437
matcher = config.LocationMatcher(store, expected_url)
3487
self.assertEqual(expected_location, matcher.location)
3489
def test_branch_name_colo(self):
3490
store = self.get_store(self)
3491
store._load_from_string(dedent("""\
3493
push_location=my{branchname}
3495
matcher = config.LocationMatcher(store, 'file:///,branch=example%3c')
3496
self.assertEqual('example<', matcher.branch_name)
3497
((_, section),) = matcher.get_sections()
3498
self.assertEqual('example<', section.locals['branchname'])
3500
def test_branch_name_basename(self):
3501
store = self.get_store(self)
3502
store._load_from_string(dedent("""\
3504
push_location=my{branchname}
3506
matcher = config.LocationMatcher(store, 'file:///parent/example%3c')
3507
self.assertEqual('example<', matcher.branch_name)
3508
((_, section),) = matcher.get_sections()
3509
self.assertEqual('example<', section.locals['branchname'])
3438
self.assertEquals(expected_location, matcher.location)
3512
3441
class TestStartingPathMatcher(TestStore):
3530
3459
def test_url_vs_local_paths(self):
3531
3460
# The matcher location is an url and the section names are local paths
3532
self.assertSectionIDs(['/foo/bar', '/foo'],
3533
'file:///foo/bar/baz', '''\
3461
sections = self.assertSectionIDs(['/foo/bar', '/foo'],
3462
'file:///foo/bar/baz', '''\
3538
3467
def test_local_path_vs_url(self):
3539
3468
# The matcher location is a local path and the section names are urls
3540
self.assertSectionIDs(['file:///foo/bar', 'file:///foo'],
3541
'/foo/bar/baz', '''\
3469
sections = self.assertSectionIDs(['file:///foo/bar', 'file:///foo'],
3470
'/foo/bar/baz', '''\
3543
3472
[file:///foo/bar]
3580
3509
# Note that 'baz' as a relpath for /foo/b* is not fully correct, but
3581
3510
# nothing really is... as far using {relpath} to append it to something
3582
3511
# else, this seems good enough though.
3583
self.assertEqual(['', 'baz', 'bar/baz'],
3512
self.assertEquals(['', 'baz', 'bar/baz'],
3584
3513
[s.locals['relpath'] for _, s in sections])
3586
3515
def test_respect_order(self):
3636
3565
store2 = config.IniFileStore()
3637
3566
store2._load_from_string('foo=baz')
3638
3567
conf = config.Stack([store1.get_sections, store2.get_sections])
3639
self.assertEqual('bar', conf.get('foo'))
3568
self.assertEquals('bar', conf.get('foo'))
3641
3570
def test_get_with_registered_default_value(self):
3642
3571
config.option_registry.register(config.Option('foo', default='bar'))
3643
3572
conf_stack = config.Stack([])
3644
self.assertEqual('bar', conf_stack.get('foo'))
3573
self.assertEquals('bar', conf_stack.get('foo'))
3646
3575
def test_get_without_registered_default_value(self):
3647
3576
config.option_registry.register(config.Option('foo'))
3648
3577
conf_stack = config.Stack([])
3649
self.assertEqual(None, conf_stack.get('foo'))
3578
self.assertEquals(None, conf_stack.get('foo'))
3651
3580
def test_get_without_default_value_for_not_registered(self):
3652
3581
conf_stack = config.Stack([])
3653
self.assertEqual(None, conf_stack.get('foo'))
3582
self.assertEquals(None, conf_stack.get('foo'))
3655
3584
def test_get_for_empty_section_callable(self):
3656
3585
conf_stack = config.Stack([lambda : []])
3657
self.assertEqual(None, conf_stack.get('foo'))
3586
self.assertEquals(None, conf_stack.get('foo'))
3659
3588
def test_get_for_broken_callable(self):
3660
3589
# Trying to use and invalid callable raises an exception on first use
3673
3602
return config.MemoryStack(content)
3675
3604
def test_override_value_from_env(self):
3676
self.overrideEnv('FOO', None)
3677
3605
self.registry.register(
3678
3606
config.Option('foo', default='bar', override_from_env=['FOO']))
3679
3607
self.overrideEnv('FOO', 'quux')
3680
3608
# Env variable provides a default taking over the option one
3681
3609
conf = self.get_conf('foo=store')
3682
self.assertEqual('quux', conf.get('foo'))
3610
self.assertEquals('quux', conf.get('foo'))
3684
3612
def test_first_override_value_from_env_wins(self):
3685
self.overrideEnv('NO_VALUE', None)
3686
self.overrideEnv('FOO', None)
3687
self.overrideEnv('BAZ', None)
3688
3613
self.registry.register(
3689
3614
config.Option('foo', default='bar',
3690
3615
override_from_env=['NO_VALUE', 'FOO', 'BAZ']))
3692
3617
self.overrideEnv('BAZ', 'baz')
3693
3618
# The first env var set wins
3694
3619
conf = self.get_conf('foo=store')
3695
self.assertEqual('foo', conf.get('foo'))
3620
self.assertEquals('foo', conf.get('foo'))
3698
3623
class TestMemoryStack(tests.TestCase):
3700
3625
def test_get(self):
3701
3626
conf = config.MemoryStack('foo=bar')
3702
self.assertEqual('bar', conf.get('foo'))
3627
self.assertEquals('bar', conf.get('foo'))
3704
3629
def test_set(self):
3705
3630
conf = config.MemoryStack('foo=bar')
3706
3631
conf.set('foo', 'baz')
3707
self.assertEqual('baz', conf.get('foo'))
3632
self.assertEquals('baz', conf.get('foo'))
3709
3634
def test_no_content(self):
3710
3635
conf = config.MemoryStack()
3713
3638
self.assertRaises(NotImplementedError, conf.get, 'foo')
3714
3639
# But a content can still be provided
3715
3640
conf.store._load_from_string('foo=bar')
3716
self.assertEqual('bar', conf.get('foo'))
3719
class TestStackIterSections(tests.TestCase):
3721
def test_empty_stack(self):
3722
conf = config.Stack([])
3723
sections = list(conf.iter_sections())
3724
self.assertLength(0, sections)
3726
def test_empty_store(self):
3727
store = config.IniFileStore()
3728
store._load_from_string('')
3729
conf = config.Stack([store.get_sections])
3730
sections = list(conf.iter_sections())
3731
self.assertLength(0, sections)
3733
def test_simple_store(self):
3734
store = config.IniFileStore()
3735
store._load_from_string('foo=bar')
3736
conf = config.Stack([store.get_sections])
3737
tuples = list(conf.iter_sections())
3738
self.assertLength(1, tuples)
3739
(found_store, found_section) = tuples[0]
3740
self.assertIs(store, found_store)
3742
def test_two_stores(self):
3743
store1 = config.IniFileStore()
3744
store1._load_from_string('foo=bar')
3745
store2 = config.IniFileStore()
3746
store2._load_from_string('bar=qux')
3747
conf = config.Stack([store1.get_sections, store2.get_sections])
3748
tuples = list(conf.iter_sections())
3749
self.assertLength(2, tuples)
3750
self.assertIs(store1, tuples[0][0])
3751
self.assertIs(store2, tuples[1][0])
3641
self.assertEquals('bar', conf.get('foo'))
3754
3644
class TestStackWithTransport(tests.TestCaseWithTransport):
3781
3671
config.ConfigHooks.install_named_hook('get', hook, None)
3782
3672
self.assertLength(0, calls)
3783
3673
value = self.conf.get('foo')
3784
self.assertEqual('bar', value)
3674
self.assertEquals('bar', value)
3785
3675
self.assertLength(1, calls)
3786
self.assertEqual((self.conf, 'foo', 'bar'), calls[0])
3676
self.assertEquals((self.conf, 'foo', 'bar'), calls[0])
3789
3679
class TestStackGetWithConverter(tests.TestCase):
3805
3695
def test_get_default_bool_None(self):
3806
3696
self.register_bool_option('foo')
3807
3697
conf = self.get_conf('')
3808
self.assertEqual(None, conf.get('foo'))
3698
self.assertEquals(None, conf.get('foo'))
3810
3700
def test_get_default_bool_True(self):
3811
3701
self.register_bool_option('foo', u'True')
3812
3702
conf = self.get_conf('')
3813
self.assertEqual(True, conf.get('foo'))
3703
self.assertEquals(True, conf.get('foo'))
3815
3705
def test_get_default_bool_False(self):
3816
3706
self.register_bool_option('foo', False)
3817
3707
conf = self.get_conf('')
3818
self.assertEqual(False, conf.get('foo'))
3708
self.assertEquals(False, conf.get('foo'))
3820
3710
def test_get_default_bool_False_as_string(self):
3821
3711
self.register_bool_option('foo', u'False')
3822
3712
conf = self.get_conf('')
3823
self.assertEqual(False, conf.get('foo'))
3713
self.assertEquals(False, conf.get('foo'))
3825
3715
def test_get_default_bool_from_env_converted(self):
3826
3716
self.register_bool_option('foo', u'True', default_from_env=['FOO'])
3827
3717
self.overrideEnv('FOO', 'False')
3828
3718
conf = self.get_conf('')
3829
self.assertEqual(False, conf.get('foo'))
3719
self.assertEquals(False, conf.get('foo'))
3831
3721
def test_get_default_bool_when_conversion_fails(self):
3832
3722
self.register_bool_option('foo', default='True')
3833
3723
conf = self.get_conf('foo=invalid boolean')
3834
self.assertEqual(True, conf.get('foo'))
3724
self.assertEquals(True, conf.get('foo'))
3836
3726
def register_integer_option(self, name,
3837
3727
default=None, default_from_env=None):
3843
3733
def test_get_default_integer_None(self):
3844
3734
self.register_integer_option('foo')
3845
3735
conf = self.get_conf('')
3846
self.assertEqual(None, conf.get('foo'))
3736
self.assertEquals(None, conf.get('foo'))
3848
3738
def test_get_default_integer(self):
3849
3739
self.register_integer_option('foo', 42)
3850
3740
conf = self.get_conf('')
3851
self.assertEqual(42, conf.get('foo'))
3741
self.assertEquals(42, conf.get('foo'))
3853
3743
def test_get_default_integer_as_string(self):
3854
3744
self.register_integer_option('foo', u'42')
3855
3745
conf = self.get_conf('')
3856
self.assertEqual(42, conf.get('foo'))
3746
self.assertEquals(42, conf.get('foo'))
3858
3748
def test_get_default_integer_from_env(self):
3859
3749
self.register_integer_option('foo', default_from_env=['FOO'])
3860
3750
self.overrideEnv('FOO', '18')
3861
3751
conf = self.get_conf('')
3862
self.assertEqual(18, conf.get('foo'))
3752
self.assertEquals(18, conf.get('foo'))
3864
3754
def test_get_default_integer_when_conversion_fails(self):
3865
3755
self.register_integer_option('foo', default='12')
3866
3756
conf = self.get_conf('foo=invalid integer')
3867
self.assertEqual(12, conf.get('foo'))
3757
self.assertEquals(12, conf.get('foo'))
3869
3759
def register_list_option(self, name, default=None, default_from_env=None):
3870
3760
l = config.ListOption(name, help='A list.', default=default,
3874
3764
def test_get_default_list_None(self):
3875
3765
self.register_list_option('foo')
3876
3766
conf = self.get_conf('')
3877
self.assertEqual(None, conf.get('foo'))
3767
self.assertEquals(None, conf.get('foo'))
3879
3769
def test_get_default_list_empty(self):
3880
3770
self.register_list_option('foo', '')
3881
3771
conf = self.get_conf('')
3882
self.assertEqual([], conf.get('foo'))
3772
self.assertEquals([], conf.get('foo'))
3884
3774
def test_get_default_list_from_env(self):
3885
3775
self.register_list_option('foo', default_from_env=['FOO'])
3886
3776
self.overrideEnv('FOO', '')
3887
3777
conf = self.get_conf('')
3888
self.assertEqual([], conf.get('foo'))
3778
self.assertEquals([], conf.get('foo'))
3890
3780
def test_get_with_list_converter_no_item(self):
3891
3781
self.register_list_option('foo', None)
3892
3782
conf = self.get_conf('foo=,')
3893
self.assertEqual([], conf.get('foo'))
3783
self.assertEquals([], conf.get('foo'))
3895
3785
def test_get_with_list_converter_many_items(self):
3896
3786
self.register_list_option('foo', None)
3897
3787
conf = self.get_conf('foo=m,o,r,e')
3898
self.assertEqual(['m', 'o', 'r', 'e'], conf.get('foo'))
3788
self.assertEquals(['m', 'o', 'r', 'e'], conf.get('foo'))
3900
3790
def test_get_with_list_converter_embedded_spaces_many_items(self):
3901
3791
self.register_list_option('foo', None)
3902
3792
conf = self.get_conf('foo=" bar", "baz "')
3903
self.assertEqual([' bar', 'baz '], conf.get('foo'))
3793
self.assertEquals([' bar', 'baz '], conf.get('foo'))
3905
3795
def test_get_with_list_converter_stripped_spaces_many_items(self):
3906
3796
self.register_list_option('foo', None)
3907
3797
conf = self.get_conf('foo= bar , baz ')
3908
self.assertEqual(['bar', 'baz'], conf.get('foo'))
3798
self.assertEquals(['bar', 'baz'], conf.get('foo'))
3911
3801
class TestIterOptionRefs(tests.TestCase):
3912
3802
"""iter_option_refs is a bit unusual, document some cases."""
3914
3804
def assertRefs(self, expected, string):
3915
self.assertEqual(expected, list(config.iter_option_refs(string)))
3805
self.assertEquals(expected, list(config.iter_option_refs(string)))
3917
3807
def test_empty(self):
3918
3808
self.assertRefs([(False, '')], '')
3946
3836
super(TestStackExpandOptions, self).setUp()
3947
3837
self.overrideAttr(config, 'option_registry', config.OptionRegistry())
3948
3838
self.registry = config.option_registry
3949
store = config.TransportIniFileStore(self.get_transport(), 'foo.conf')
3950
self.conf = config.Stack([store.get_sections], store)
3839
self.conf = build_branch_stack(self)
3952
3841
def assertExpansion(self, expected, string, env=None):
3953
self.assertEqual(expected, self.conf.expand_options(string, env))
3842
self.assertEquals(expected, self.conf.expand_options(string, env))
3955
3844
def test_no_expansion(self):
3956
3845
self.assertExpansion('foo', 'foo')
3958
3847
def test_expand_default_value(self):
3959
3848
self.conf.store._load_from_string('bar=baz')
3960
3849
self.registry.register(config.Option('foo', default=u'{bar}'))
3961
self.assertEqual('baz', self.conf.get('foo', expand=True))
3850
self.assertEquals('baz', self.conf.get('foo', expand=True))
3963
3852
def test_expand_default_from_env(self):
3964
3853
self.conf.store._load_from_string('bar=baz')
3965
3854
self.registry.register(config.Option('foo', default_from_env=['FOO']))
3966
3855
self.overrideEnv('FOO', '{bar}')
3967
self.assertEqual('baz', self.conf.get('foo', expand=True))
3856
self.assertEquals('baz', self.conf.get('foo', expand=True))
3969
3858
def test_expand_default_on_failed_conversion(self):
3970
3859
self.conf.store._load_from_string('baz=bogus\nbar=42\nfoo={baz}')
3971
3860
self.registry.register(
3972
3861
config.Option('foo', default=u'{bar}',
3973
3862
from_unicode=config.int_from_store))
3974
self.assertEqual(42, self.conf.get('foo', expand=True))
3863
self.assertEquals(42, self.conf.get('foo', expand=True))
3976
3865
def test_env_adding_options(self):
3977
3866
self.assertExpansion('bar', '{foo}', {'foo': 'bar'})
3988
3877
self.assertRaises(errors.ExpandingUnknownOption,
3989
3878
self.conf.expand_options, '{foo}')
3991
def test_illegal_def_is_ignored(self):
3992
self.assertExpansion('{1,2}', '{1,2}')
3993
self.assertExpansion('{ }', '{ }')
3994
self.assertExpansion('${Foo,f}', '${Foo,f}')
3996
3880
def test_indirect_ref(self):
3997
3881
self.conf.store._load_from_string('''
4044
self.registry.register(config.ListOption('list'))
4045
# Register an intermediate option as a list to ensure no conversion
4046
# happen while expanding. Conversion should only occur for the original
4047
# option ('list' here).
4048
self.registry.register(config.ListOption('baz'))
4049
self.assertEqual(['start', 'middle', 'end'],
3928
self.registry.register(
3929
config.ListOption('list'))
3930
self.assertEquals(['start', 'middle', 'end'],
4050
3931
self.conf.get('list', expand=True))
4052
3933
def test_pathologically_hidden_list(self):
4137
4018
stack = config.LocationStack('/home/user/project/')
4138
self.assertEqual('', stack.get('base', expand=True))
4139
self.assertEqual('', stack.get('rel', expand=True))
4019
self.assertEquals('', stack.get('base', expand=True))
4020
self.assertEquals('', stack.get('rel', expand=True))
4141
4022
def test_expand_basename_locally(self):
4142
4023
l_store = config.LocationStore()
4197
4078
stack = config.LocationStack('/home/user/project/branch')
4198
self.assertEqual('glob-bar', stack.get('lbar', expand=True))
4199
self.assertEqual('loc-foo/branch', stack.get('gfoo', expand=True))
4079
self.assertEquals('glob-bar', stack.get('lbar', expand=True))
4080
self.assertEquals('loc-foo/branch', stack.get('gfoo', expand=True))
4201
4082
def test_locals_dont_leak(self):
4202
4083
"""Make sure we chose the right local in presence of several sections.
4221
4102
def test_simple_set(self):
4222
4103
conf = self.get_stack(self)
4223
self.assertEqual(None, conf.get('foo'))
4104
self.assertEquals(None, conf.get('foo'))
4224
4105
conf.set('foo', 'baz')
4225
4106
# Did we get it back ?
4226
self.assertEqual('baz', conf.get('foo'))
4107
self.assertEquals('baz', conf.get('foo'))
4228
4109
def test_set_creates_a_new_section(self):
4229
4110
conf = self.get_stack(self)
4230
4111
conf.set('foo', 'baz')
4231
self.assertEqual, 'baz', conf.get('foo')
4112
self.assertEquals, 'baz', conf.get('foo')
4233
4114
def test_set_hook(self):
4442
4314
user = credentials['user']
4443
4315
password = credentials['password']
4444
self.assertEqual(expected_user, user)
4445
self.assertEqual(expected_password, password)
4316
self.assertEquals(expected_user, user)
4317
self.assertEquals(expected_password, password)
4447
4319
def test_empty_config(self):
4448
4320
conf = config.AuthenticationConfig(_file=StringIO())
4449
self.assertEqual({}, conf._get_config())
4321
self.assertEquals({}, conf._get_config())
4450
4322
self._got_user_passwd(None, None, conf, 'http', 'foo.net')
4452
4324
def test_non_utf8_config(self):
4649
4521
port=99, path='/foo',
4651
4523
CREDENTIALS = {'name': 'name', 'user': 'user', 'password': 'password',
4652
'verify_certificates': False, 'scheme': 'scheme',
4653
'host': 'host', 'port': 99, 'path': '/foo',
4524
'verify_certificates': False, 'scheme': 'scheme',
4525
'host': 'host', 'port': 99, 'path': '/foo',
4654
4526
'realm': 'realm'}
4655
4527
self.assertEqual(CREDENTIALS, credentials)
4656
4528
credentials_from_disk = config.AuthenticationConfig().get_credentials(
4664
4536
self.assertIs(None, conf._get_config().get('name'))
4665
4537
credentials = conf.get_credentials(host='host', scheme='scheme')
4666
4538
CREDENTIALS = {'name': 'name2', 'user': 'user2', 'password':
4667
'password', 'verify_certificates': True,
4668
'scheme': 'scheme', 'host': 'host', 'port': None,
4539
'password', 'verify_certificates': True,
4540
'scheme': 'scheme', 'host': 'host', 'port': None,
4669
4541
'path': None, 'realm': None}
4670
4542
self.assertEqual(CREDENTIALS, credentials)
4689
4561
stdout=stdout, stderr=stderr)
4690
4562
# We use an empty conf so that the user is always prompted
4691
4563
conf = config.AuthenticationConfig()
4692
self.assertEqual(password,
4564
self.assertEquals(password,
4693
4565
conf.get_password(scheme, host, user, port=port,
4694
4566
realm=realm, path=path))
4695
self.assertEqual(expected_prompt, stderr.getvalue())
4696
self.assertEqual('', stdout.getvalue())
4567
self.assertEquals(expected_prompt, stderr.getvalue())
4568
self.assertEquals('', stdout.getvalue())
4698
4570
def _check_default_username_prompt(self, expected_prompt_format, scheme,
4699
4571
host=None, port=None, realm=None,
4710
4582
stdout=stdout, stderr=stderr)
4711
4583
# We use an empty conf so that the user is always prompted
4712
4584
conf = config.AuthenticationConfig()
4713
self.assertEqual(username, conf.get_user(scheme, host, port=port,
4585
self.assertEquals(username, conf.get_user(scheme, host, port=port,
4714
4586
realm=realm, path=path, ask=True))
4715
self.assertEqual(expected_prompt, stderr.getvalue())
4716
self.assertEqual('', stdout.getvalue())
4587
self.assertEquals(expected_prompt, stderr.getvalue())
4588
self.assertEquals('', stdout.getvalue())
4718
4590
def test_username_defaults_prompts(self):
4719
4591
# HTTP prompts can't be tested here, see test_http.py
4805
4677
config.credential_store_registry.register("stub", store, fallback=True)
4806
4678
conf = config.AuthenticationConfig(_file=StringIO())
4807
4679
creds = conf.get_credentials("http", "example.com")
4808
self.assertEqual("joe", creds["user"])
4809
self.assertEqual("secret", creds["password"])
4680
self.assertEquals("joe", creds["user"])
4681
self.assertEquals("secret", creds["password"])
4812
4684
class StubCredentialStore(config.CredentialStore):
4858
4730
def test_fallback_none_registered(self):
4859
4731
r = config.CredentialStoreRegistry()
4860
self.assertEqual(None,
4732
self.assertEquals(None,
4861
4733
r.get_fallback_credentials("http", "example.com"))
4863
4735
def test_register(self):
4864
4736
r = config.CredentialStoreRegistry()
4865
4737
r.register("stub", StubCredentialStore(), fallback=False)
4866
4738
r.register("another", StubCredentialStore(), fallback=True)
4867
self.assertEqual(["another", "stub"], r.keys())
4739
self.assertEquals(["another", "stub"], r.keys())
4869
4741
def test_register_lazy(self):
4870
4742
r = config.CredentialStoreRegistry()
4871
4743
r.register_lazy("stub", "bzrlib.tests.test_config",
4872
4744
"StubCredentialStore", fallback=False)
4873
self.assertEqual(["stub"], r.keys())
4745
self.assertEquals(["stub"], r.keys())
4874
4746
self.assertIsInstance(r.get_credential_store("stub"),
4875
4747
StubCredentialStore)
4878
4750
r = config.CredentialStoreRegistry()
4879
4751
r.register("stub1", None, fallback=False)
4880
4752
r.register("stub2", None, fallback=True)
4881
self.assertEqual(False, r.is_fallback("stub1"))
4882
self.assertEqual(True, r.is_fallback("stub2"))
4753
self.assertEquals(False, r.is_fallback("stub1"))
4754
self.assertEquals(True, r.is_fallback("stub2"))
4884
4756
def test_no_fallback(self):
4885
4757
r = config.CredentialStoreRegistry()
4886
4758
store = CountingCredentialStore()
4887
4759
r.register("count", store, fallback=False)
4888
self.assertEqual(None,
4760
self.assertEquals(None,
4889
4761
r.get_fallback_credentials("http", "example.com"))
4890
self.assertEqual(0, store._calls)
4762
self.assertEquals(0, store._calls)
4892
4764
def test_fallback_credentials(self):
4893
4765
r = config.CredentialStoreRegistry()
4896
4768
"somebody", "geheim")
4897
4769
r.register("stub", store, fallback=True)
4898
4770
creds = r.get_fallback_credentials("http", "example.com")
4899
self.assertEqual("somebody", creds["user"])
4900
self.assertEqual("geheim", creds["password"])
4771
self.assertEquals("somebody", creds["user"])
4772
self.assertEquals("geheim", creds["password"])
4902
4774
def test_fallback_first_wins(self):
4903
4775
r = config.CredentialStoreRegistry()
4920
4792
r = config.credential_store_registry
4921
4793
plain_text = r.get_credential_store()
4922
4794
decoded = plain_text.decode_password(dict(password='secret'))
4923
self.assertEqual('secret', decoded)
4926
class TestBase64CredentialStore(tests.TestCase):
4928
def test_decode_password(self):
4929
r = config.credential_store_registry
4930
plain_text = r.get_credential_store('base64')
4931
decoded = plain_text.decode_password(dict(password='c2VjcmV0'))
4932
self.assertEqual('secret', decoded)
4795
self.assertEquals('secret', decoded)
4935
4798
# FIXME: Once we have a way to declare authentication to all test servers, we
4963
4826
self.assertIsNot(None, realname)
4964
4827
self.assertIsNot(None, address)
4966
self.assertEqual((None, None), (realname, address))
4969
class TestDefaultMailDomain(tests.TestCaseInTempDir):
4970
"""Test retrieving default domain from mailname file"""
4972
def test_default_mail_domain_simple(self):
4973
f = file('simple', 'w')
4975
f.write("domainname.com\n")
4978
r = config._get_default_mail_domain('simple')
4979
self.assertEqual('domainname.com', r)
4981
def test_default_mail_domain_no_eol(self):
4982
f = file('no_eol', 'w')
4984
f.write("domainname.com")
4987
r = config._get_default_mail_domain('no_eol')
4988
self.assertEqual('domainname.com', r)
4990
def test_default_mail_domain_multiple_lines(self):
4991
f = file('multiple_lines', 'w')
4993
f.write("domainname.com\nsome other text\n")
4996
r = config._get_default_mail_domain('multiple_lines')
4997
self.assertEqual('domainname.com', r)
4829
self.assertEquals((None, None), (realname, address))
5000
4832
class EmailOptionTests(tests.TestCase):
5004
4836
# BZR_EMAIL takes precedence over EMAIL
5005
4837
self.overrideEnv('BZR_EMAIL', 'jelmer@samba.org')
5006
4838
self.overrideEnv('EMAIL', 'jelmer@apache.org')
5007
self.assertEqual('jelmer@samba.org', conf.get('email'))
4839
self.assertEquals('jelmer@samba.org', conf.get('email'))
5009
4841
def test_default_email_uses_EMAIL(self):
5010
4842
conf = config.MemoryStack('')
5011
4843
self.overrideEnv('BZR_EMAIL', None)
5012
4844
self.overrideEnv('EMAIL', 'jelmer@apache.org')
5013
self.assertEqual('jelmer@apache.org', conf.get('email'))
4845
self.assertEquals('jelmer@apache.org', conf.get('email'))
5015
4847
def test_BZR_EMAIL_overrides(self):
5016
4848
conf = config.MemoryStack('email=jelmer@debian.org')
5017
4849
self.overrideEnv('BZR_EMAIL', 'jelmer@apache.org')
5018
self.assertEqual('jelmer@apache.org', conf.get('email'))
4850
self.assertEquals('jelmer@apache.org', conf.get('email'))
5019
4851
self.overrideEnv('BZR_EMAIL', None)
5020
4852
self.overrideEnv('EMAIL', 'jelmer@samba.org')
5021
self.assertEqual('jelmer@debian.org', conf.get('email'))
5024
class MailClientOptionTests(tests.TestCase):
5026
def test_default(self):
5027
conf = config.MemoryStack('')
5028
client = conf.get('mail_client')
5029
self.assertIs(client, mail_client.DefaultMail)
5031
def test_evolution(self):
5032
conf = config.MemoryStack('mail_client=evolution')
5033
client = conf.get('mail_client')
5034
self.assertIs(client, mail_client.Evolution)
5036
def test_kmail(self):
5037
conf = config.MemoryStack('mail_client=kmail')
5038
client = conf.get('mail_client')
5039
self.assertIs(client, mail_client.KMail)
5041
def test_mutt(self):
5042
conf = config.MemoryStack('mail_client=mutt')
5043
client = conf.get('mail_client')
5044
self.assertIs(client, mail_client.Mutt)
5046
def test_thunderbird(self):
5047
conf = config.MemoryStack('mail_client=thunderbird')
5048
client = conf.get('mail_client')
5049
self.assertIs(client, mail_client.Thunderbird)
5051
def test_explicit_default(self):
5052
conf = config.MemoryStack('mail_client=default')
5053
client = conf.get('mail_client')
5054
self.assertIs(client, mail_client.DefaultMail)
5056
def test_editor(self):
5057
conf = config.MemoryStack('mail_client=editor')
5058
client = conf.get('mail_client')
5059
self.assertIs(client, mail_client.Editor)
5061
def test_mapi(self):
5062
conf = config.MemoryStack('mail_client=mapi')
5063
client = conf.get('mail_client')
5064
self.assertIs(client, mail_client.MAPIClient)
5066
def test_xdg_email(self):
5067
conf = config.MemoryStack('mail_client=xdg-email')
5068
client = conf.get('mail_client')
5069
self.assertIs(client, mail_client.XDGEmail)
5071
def test_unknown(self):
5072
conf = config.MemoryStack('mail_client=firebird')
5073
self.assertRaises(errors.ConfigOptionValueError, conf.get,
4853
self.assertEquals('jelmer@debian.org', conf.get('email'))