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
28
27
from bzrlib import (
37
registry as _mod_registry,
681
678
def test_saved_with_content(self):
682
679
content = 'foo = bar\n'
683
conf = config.IniBasedConfig.from_string(
684
content, file_name='./test.conf', save=True)
680
config.IniBasedConfig.from_string(content, file_name='./test.conf',
685
682
self.assertFileEqual(content, 'test.conf')
688
class TestIniConfigOptionExpansionDefaultValue(tests.TestCaseInTempDir):
689
"""What is the default value of expand for config options.
691
This is an opt-in beta feature used to evaluate whether or not option
692
references can appear in dangerous place raising exceptions, disapearing
693
(and as such corrupting data) or if it's safe to activate the option by
696
Note that these tests relies on config._expand_default_value being already
697
overwritten in the parent class setUp.
701
super(TestIniConfigOptionExpansionDefaultValue, self).setUp()
705
self.warnings.append(args[0] % args[1:])
706
self.overrideAttr(trace, 'warning', warning)
708
def get_config(self, expand):
709
c = config.GlobalConfig.from_string('bzr.config.expand=%s' % (expand,),
713
def assertExpandIs(self, expected):
714
actual = config._get_expand_default_value()
715
#self.config.get_user_option_as_bool('bzr.config.expand')
716
self.assertEquals(expected, actual)
718
def test_default_is_None(self):
719
self.assertEquals(None, config._expand_default_value)
721
def test_default_is_False_even_if_None(self):
722
self.config = self.get_config(None)
723
self.assertExpandIs(False)
725
def test_default_is_False_even_if_invalid(self):
726
self.config = self.get_config('<your choice>')
727
self.assertExpandIs(False)
729
# Huh ? My choice is False ? Thanks, always happy to hear that :D
730
# Wait, you've been warned !
731
self.assertLength(1, self.warnings)
733
'Value "<your choice>" is not a boolean for "bzr.config.expand"',
736
def test_default_is_True(self):
737
self.config = self.get_config(True)
738
self.assertExpandIs(True)
740
def test_default_is_False(self):
741
self.config = self.get_config(False)
742
self.assertExpandIs(False)
745
685
class TestIniConfigOptionExpansion(tests.TestCase):
746
686
"""Test option expansion from the IniConfig level.
842
782
# Nope, it's either a string or a list, and the list wins as soon as a
843
783
# ',' appears, so the string concatenation never occur.
844
self.assertEquals(['{foo', '}', '{', 'bar}'],
784
self.assertEqual(['{foo', '}', '{', 'bar}'],
845
785
conf.get_user_option('hidden', expand=True))
923
863
def test_simple_read_access(self):
924
self.assertEquals('1', self.config.get_user_option('one'))
864
self.assertEqual('1', self.config.get_user_option('one'))
926
866
def test_simple_write_access(self):
927
867
self.config.set_user_option('one', 'one')
928
self.assertEquals('one', self.config.get_user_option('one'))
868
self.assertEqual('one', self.config.get_user_option('one'))
930
870
def test_listen_to_the_last_speaker(self):
932
872
c2 = self.get_existing_config()
933
873
c1.set_user_option('one', 'ONE')
934
874
c2.set_user_option('two', 'TWO')
935
self.assertEquals('ONE', c1.get_user_option('one'))
936
self.assertEquals('TWO', c2.get_user_option('two'))
875
self.assertEqual('ONE', c1.get_user_option('one'))
876
self.assertEqual('TWO', c2.get_user_option('two'))
937
877
# The second update respect the first one
938
self.assertEquals('ONE', c2.get_user_option('one'))
878
self.assertEqual('ONE', c2.get_user_option('one'))
940
880
def test_last_speaker_wins(self):
941
881
# If the same config is not shared, the same variable modified twice
944
884
c2 = self.get_existing_config()
945
885
c1.set_user_option('one', 'c1')
946
886
c2.set_user_option('one', 'c2')
947
self.assertEquals('c2', c2._get_user_option('one'))
887
self.assertEqual('c2', c2._get_user_option('one'))
948
888
# The first modification is still available until another refresh
950
self.assertEquals('c1', c1._get_user_option('one'))
890
self.assertEqual('c1', c1._get_user_option('one'))
951
891
c1.set_user_option('two', 'done')
952
self.assertEquals('c2', c1._get_user_option('one'))
892
self.assertEqual('c2', c1._get_user_option('one'))
954
894
def test_writes_are_serialized(self):
980
920
self.assertTrue(c1._lock.is_held)
981
921
self.assertRaises(errors.LockContention,
982
922
c2.set_user_option, 'one', 'c2')
983
self.assertEquals('c1', c1.get_user_option('one'))
923
self.assertEqual('c1', c1.get_user_option('one'))
984
924
# Let the lock be released
985
925
after_writing.set()
986
926
writing_done.wait()
987
927
c2.set_user_option('one', 'c2')
988
self.assertEquals('c2', c2.get_user_option('one'))
928
self.assertEqual('c2', c2.get_user_option('one'))
990
930
def test_read_while_writing(self):
1013
953
# Ensure the thread is ready to write
1014
954
ready_to_write.wait()
1015
955
self.assertTrue(c1._lock.is_held)
1016
self.assertEquals('c1', c1.get_user_option('one'))
956
self.assertEqual('c1', c1.get_user_option('one'))
1017
957
# If we read during the write, we get the old value
1018
958
c2 = self.get_existing_config()
1019
self.assertEquals('1', c2.get_user_option('one'))
959
self.assertEqual('1', c2.get_user_option('one'))
1020
960
# Let the writing occur and ensure it occurred
1021
961
do_writing.set()
1022
962
writing_done.wait()
1023
963
# Now we get the updated value
1024
964
c3 = self.get_existing_config()
1025
self.assertEquals('c1', c3.get_user_option('one'))
965
self.assertEqual('c1', c3.get_user_option('one'))
1028
968
class TestGetUserOptionAs(TestIniConfig):
1043
983
self.overrideAttr(trace, 'warning', warning)
1044
984
msg = 'Value "%s" is not a boolean for "%s"'
1045
985
self.assertIs(None, get_bool('an_invalid_bool'))
1046
self.assertEquals(msg % ('maybe', 'an_invalid_bool'), warnings[0])
986
self.assertEqual(msg % ('maybe', 'an_invalid_bool'), warnings[0])
1048
988
self.assertIs(None, get_bool('not_defined_in_this_config'))
1049
self.assertEquals([], warnings)
989
self.assertEqual([], warnings)
1051
991
def test_get_user_option_as_list(self):
1052
992
conf, parser = self.make_config_parser("""
1238
1187
my_config = config.GlobalConfig()
1239
1188
self.assertEqual(None, my_config._get_user_id())
1241
def test_configured_editor(self):
1242
my_config = config.GlobalConfig.from_string(sample_config_text)
1243
editor = self.applyDeprecated(
1244
deprecated_in((2, 4, 0)), my_config.get_editor)
1245
self.assertEqual('vim', editor)
1247
1190
def test_signatures_always(self):
1248
1191
my_config = config.GlobalConfig.from_string(sample_always_signatures)
1249
1192
self.assertEqual(config.CHECK_NEVER,
1723
1668
if location_config is None:
1724
1669
location_config = sample_branches_text
1726
my_global_config = config.GlobalConfig.from_string(global_config,
1728
my_location_config = config.LocationConfig.from_string(
1729
location_config, my_branch.base, save=True)
1671
config.GlobalConfig.from_string(global_config, save=True)
1672
config.LocationConfig.from_string(location_config, my_branch.base,
1730
1674
my_config = config.BranchConfig(my_branch)
1731
1675
self.my_config = my_config
1732
1676
self.my_location_config = my_config._get_location_config()
1797
1741
location_config=None, branch_data_config=None):
1798
1742
my_branch = FakeBranch(location)
1799
1743
if global_config is not None:
1800
my_global_config = config.GlobalConfig.from_string(global_config,
1744
config.GlobalConfig.from_string(global_config, save=True)
1802
1745
if location_config is not None:
1803
my_location_config = config.LocationConfig.from_string(
1804
location_config, my_branch.base, save=True)
1746
config.LocationConfig.from_string(location_config, my_branch.base,
1805
1748
my_config = config.BranchConfig(my_branch)
1806
1749
if branch_data_config is not None:
1807
1750
my_config.branch.control_files.files['branch.conf'] = \
1903
1846
location='http://example.com/specific')
1904
1847
self.assertEqual(my_config.get_user_option('option'), 'exact')
1906
def test_get_mail_client(self):
1907
config = self.get_branch_config()
1908
client = config.get_mail_client()
1909
self.assertIsInstance(client, mail_client.DefaultMail)
1912
config.set_user_option('mail_client', 'evolution')
1913
client = config.get_mail_client()
1914
self.assertIsInstance(client, mail_client.Evolution)
1916
config.set_user_option('mail_client', 'kmail')
1917
client = config.get_mail_client()
1918
self.assertIsInstance(client, mail_client.KMail)
1920
config.set_user_option('mail_client', 'mutt')
1921
client = config.get_mail_client()
1922
self.assertIsInstance(client, mail_client.Mutt)
1924
config.set_user_option('mail_client', 'thunderbird')
1925
client = config.get_mail_client()
1926
self.assertIsInstance(client, mail_client.Thunderbird)
1929
config.set_user_option('mail_client', 'default')
1930
client = config.get_mail_client()
1931
self.assertIsInstance(client, mail_client.DefaultMail)
1933
config.set_user_option('mail_client', 'editor')
1934
client = config.get_mail_client()
1935
self.assertIsInstance(client, mail_client.Editor)
1937
config.set_user_option('mail_client', 'mapi')
1938
client = config.get_mail_client()
1939
self.assertIsInstance(client, mail_client.MAPIClient)
1941
config.set_user_option('mail_client', 'xdg-email')
1942
client = config.get_mail_client()
1943
self.assertIsInstance(client, mail_client.XDGEmail)
1945
config.set_user_option('mail_client', 'firebird')
1946
self.assertRaises(errors.UnknownMailClient, config.get_mail_client)
1949
1850
class TestMailAddressExtraction(tests.TestCase):
2097
1998
config.OldConfigHooks.uninstall_named_hook, 'get', None)
2098
1999
self.assertLength(0, calls)
2099
2000
actual_value = conf.get_user_option(name)
2100
self.assertEquals(value, actual_value)
2001
self.assertEqual(value, actual_value)
2101
2002
self.assertLength(1, calls)
2102
self.assertEquals((conf, name, value), calls[0])
2003
self.assertEqual((conf, name, value), calls[0])
2104
2005
def test_get_hook_bazaar(self):
2105
2006
self.assertGetHook(self.bazaar_config, 'file', 'bazaar')
2228
2129
config.OldConfigHooks.uninstall_named_hook, 'get', None)
2229
2130
self.assertLength(0, calls)
2230
2131
actual_value = conf.get_option(name)
2231
self.assertEquals(value, actual_value)
2132
self.assertEqual(value, actual_value)
2232
2133
self.assertLength(1, calls)
2233
self.assertEquals((conf, name, value), calls[0])
2134
self.assertEqual((conf, name, value), calls[0])
2235
2136
def test_get_hook_remote_branch(self):
2236
2137
remote_branch = branch.Branch.open(self.get_url('tree'))
2237
2138
self.assertGetHook(remote_branch._get_config(), 'file', 'branch')
2239
2140
def test_get_hook_remote_bzrdir(self):
2240
remote_bzrdir = bzrdir.BzrDir.open(self.get_url('tree'))
2141
remote_bzrdir = controldir.ControlDir.open(self.get_url('tree'))
2241
2142
conf = remote_bzrdir._get_config()
2242
2143
conf.set_option('remotedir', 'file')
2243
2144
self.assertGetHook(conf, 'file', 'remotedir')
2319
2220
def test_save_hook_remote_bzrdir(self):
2320
2221
remote_branch = branch.Branch.open(self.get_url('tree'))
2321
2222
self.addCleanup(remote_branch.lock_write().unlock)
2322
remote_bzrdir = bzrdir.BzrDir.open(self.get_url('tree'))
2223
remote_bzrdir = controldir.ControlDir.open(self.get_url('tree'))
2323
2224
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}}')
2326
2271
class TestOption(tests.TestCase):
2328
2273
def test_default_value(self):
2329
2274
opt = config.Option('foo', default='bar')
2330
self.assertEquals('bar', opt.get_default())
2275
self.assertEqual('bar', opt.get_default())
2332
2277
def test_callable_default_value(self):
2333
2278
def bar_as_unicode():
2335
2280
opt = config.Option('foo', default=bar_as_unicode)
2336
self.assertEquals('bar', opt.get_default())
2281
self.assertEqual('bar', opt.get_default())
2338
2283
def test_default_value_from_env(self):
2339
2284
opt = config.Option('foo', default='bar', default_from_env=['FOO'])
2340
2285
self.overrideEnv('FOO', 'quux')
2341
2286
# Env variable provides a default taking over the option one
2342
self.assertEquals('quux', opt.get_default())
2287
self.assertEqual('quux', opt.get_default())
2344
2289
def test_first_default_value_from_env_wins(self):
2345
2290
opt = config.Option('foo', default='bar',
2362
2307
opt = config.Option('foo', default=bar_not_unicode)
2363
2308
self.assertRaises(AssertionError, opt.get_default)
2366
class TestOptionConverterMixin(object):
2310
def test_get_help_topic(self):
2311
opt = config.Option('foo')
2312
self.assertEqual('foo', opt.get_help_topic())
2315
class TestOptionConverter(tests.TestCase):
2368
2317
def assertConverted(self, expected, opt, value):
2369
self.assertEquals(expected, opt.convert_from_unicode(None, value))
2318
self.assertEqual(expected, opt.convert_from_unicode(None, value))
2371
def assertWarns(self, opt, value):
2320
def assertCallsWarning(self, opt, value):
2373
2323
def warning(*args):
2374
2324
warnings.append(args[0] % args[1:])
2375
2325
self.overrideAttr(trace, 'warning', warning)
2376
self.assertEquals(None, opt.convert_from_unicode(None, value))
2326
self.assertEqual(None, opt.convert_from_unicode(None, value))
2377
2327
self.assertLength(1, warnings)
2379
2329
'Value "%s" is not valid for "%s"' % (value, opt.name),
2382
def assertErrors(self, opt, value):
2332
def assertCallsError(self, opt, value):
2383
2333
self.assertRaises(errors.ConfigOptionValueError,
2384
2334
opt.convert_from_unicode, None, value)
2386
2336
def assertConvertInvalid(self, opt, invalid_value):
2387
2337
opt.invalid = None
2388
self.assertEquals(None, opt.convert_from_unicode(None, invalid_value))
2338
self.assertEqual(None, opt.convert_from_unicode(None, invalid_value))
2389
2339
opt.invalid = 'warning'
2390
self.assertWarns(opt, invalid_value)
2340
self.assertCallsWarning(opt, invalid_value)
2391
2341
opt.invalid = 'error'
2392
self.assertErrors(opt, invalid_value)
2395
class TestOptionWithBooleanConverter(tests.TestCase, TestOptionConverterMixin):
2342
self.assertCallsError(opt, invalid_value)
2345
class TestOptionWithBooleanConverter(TestOptionConverter):
2397
2347
def get_option(self):
2398
2348
return config.Option('foo', help='A boolean.',
2439
2389
def test_convert_invalid(self):
2440
2390
opt = self.get_option()
2441
2391
self.assertConvertInvalid(opt, u'not-a-unit')
2442
self.assertConvertInvalid(opt, u'Gb') # Forgot the int
2443
self.assertConvertInvalid(opt, u'1b') # Forgot the unit
2392
self.assertConvertInvalid(opt, u'Gb') # Forgot the value
2393
self.assertConvertInvalid(opt, u'1b') # Forgot the unit
2444
2394
self.assertConvertInvalid(opt, u'1GG')
2445
2395
self.assertConvertInvalid(opt, u'1Mbb')
2446
2396
self.assertConvertInvalid(opt, u'1MM')
2480
2430
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())
2483
2481
class TestOptionRegistry(tests.TestCase):
2485
2483
def setUp(self):
2496
2494
def test_registered_help(self):
2497
2495
opt = config.Option('foo', help='A simple option')
2498
2496
self.registry.register(opt)
2499
self.assertEquals('A simple option', self.registry.get_help('foo'))
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,'))
2501
2505
lazy_option = config.Option('lazy_foo', help='Lazy help')
2508
2512
def test_registered_lazy_help(self):
2509
2513
self.registry.register_lazy('lazy_foo', self.__module__,
2510
2514
'TestOptionRegistry.lazy_option')
2511
self.assertEquals('Lazy help', self.registry.get_help('lazy_foo'))
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')
2514
2531
class TestRegisteredOptions(tests.TestCase):
2524
2541
def test_proper_name(self):
2525
2542
# An option should be registered under its own name, this can't be
2526
2543
# checked at registration time for the lazy ones.
2527
self.assertEquals(self.option_name, self.option.name)
2544
self.assertEqual(self.option_name, self.option.name)
2529
2546
def test_help_is_set(self):
2530
2547
option_help = self.registry.get_help(self.option_name)
2531
self.assertNotEquals(None, option_help)
2532
2548
# Come on, think about the user, he really wants to know what the
2533
2549
# option is about
2534
2550
self.assertIsNot(None, option_help)
2535
self.assertNotEquals('', option_help)
2551
self.assertNotEqual('', option_help)
2538
2554
class TestSection(tests.TestCase):
2543
2559
def test_get_a_value(self):
2544
2560
a_dict = dict(foo='bar')
2545
2561
section = config.Section('myID', a_dict)
2546
self.assertEquals('bar', section.get('foo'))
2562
self.assertEqual('bar', section.get('foo'))
2548
2564
def test_get_unknown_option(self):
2549
2565
a_dict = dict()
2550
2566
section = config.Section(None, a_dict)
2551
self.assertEquals('out of thin air',
2567
self.assertEqual('out of thin air',
2552
2568
section.get('foo', 'out of thin air'))
2554
2570
def test_options_is_shared(self):
2568
2584
a_dict = dict(foo='bar')
2569
2585
section = self.get_section(a_dict)
2570
2586
section.set('foo', 'new_value')
2571
self.assertEquals('new_value', section.get('foo'))
2587
self.assertEqual('new_value', section.get('foo'))
2572
2588
# The change appears in the shared section
2573
self.assertEquals('new_value', a_dict.get('foo'))
2589
self.assertEqual('new_value', a_dict.get('foo'))
2574
2590
# We keep track of the change
2575
2591
self.assertTrue('foo' in section.orig)
2576
self.assertEquals('bar', section.orig.get('foo'))
2592
self.assertEqual('bar', section.orig.get('foo'))
2578
2594
def test_set_preserve_original_once(self):
2579
2595
a_dict = dict(foo='bar')
2582
2598
section.set('foo', 'second_value')
2583
2599
# We keep track of the original value
2584
2600
self.assertTrue('foo' in section.orig)
2585
self.assertEquals('bar', section.orig.get('foo'))
2601
self.assertEqual('bar', section.orig.get('foo'))
2587
2603
def test_remove(self):
2588
2604
a_dict = dict(foo='bar')
2589
2605
section = self.get_section(a_dict)
2590
2606
section.remove('foo')
2591
2607
# We get None for unknown options via the default value
2592
self.assertEquals(None, section.get('foo'))
2608
self.assertEqual(None, section.get('foo'))
2593
2609
# Or we just get the default value
2594
self.assertEquals('unknown', section.get('foo', 'unknown'))
2610
self.assertEqual('unknown', section.get('foo', 'unknown'))
2595
2611
self.assertFalse('foo' in section.options)
2596
2612
# We keep track of the deletion
2597
2613
self.assertTrue('foo' in section.orig)
2598
self.assertEquals('bar', section.orig.get('foo'))
2614
self.assertEqual('bar', section.orig.get('foo'))
2600
2616
def test_remove_new_option(self):
2601
2617
a_dict = dict()
2648
2664
def test_multiple_overrides(self):
2649
2665
self.store._from_cmdline(['a=b', 'x=y'])
2650
2666
section = self.get_section()
2651
self.assertEquals('b', section.get('a'))
2652
self.assertEquals('y', section.get('x'))
2667
self.assertEqual('b', section.get('a'))
2668
self.assertEqual('y', section.get('x'))
2654
2670
def test_wrong_syntax(self):
2655
2671
self.assertRaises(errors.BzrCommandError,
2689
2705
def test_building_delays_load(self):
2690
2706
store = self.get_store(self)
2691
self.assertEquals(False, store.is_loaded())
2707
self.assertEqual(False, store.is_loaded())
2692
2708
store._load_from_string('')
2693
self.assertEquals(True, store.is_loaded())
2709
self.assertEqual(True, store.is_loaded())
2695
2711
def test_get_no_sections_for_empty(self):
2696
2712
store = self.get_store(self)
2697
2713
store._load_from_string('')
2698
self.assertEquals([], list(store.get_sections()))
2714
self.assertEqual([], list(store.get_sections()))
2700
2716
def test_get_default_section(self):
2701
2717
store = self.get_store(self)
2781
2797
value = conf.get('a_section')
2782
2798
# Urgh, despite 'conf' asking for the no-name section, we get the
2783
2799
# content of another section as a dict o_O
2784
self.assertEquals({'a': '1'}, value)
2800
self.assertEqual({'a': '1'}, value)
2785
2801
unquoted = conf.store.unquote(value)
2786
2802
# Which cannot be unquoted but shouldn't crash either (the use cases
2787
2803
# are getting the value or displaying it. In the later case, '%s' will
2789
self.assertEquals({'a': '1'}, unquoted)
2790
self.assertEquals("{u'a': u'1'}", '%s' % (unquoted,))
2805
self.assertEqual({'a': '1'}, unquoted)
2806
self.assertEqual("{u'a': u'1'}", '%s' % (unquoted,))
2793
2809
class TestIniFileStoreContent(tests.TestCaseWithTransport):
2909
2925
'branch.conf is *always* created when a branch is initialized')
2910
2926
store = self.get_store(self)
2912
self.assertEquals(False, self.has_store(store))
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)
2914
2944
def test_save_emptied_succeeds(self):
2915
2945
store = self.get_store(self)
2916
2946
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)
2917
2952
section = store.get_mutable_section(None)
2918
2953
section.remove('foo')
2920
self.assertEquals(True, self.has_store(store))
2955
self.assertEqual(True, self.has_store(store))
2921
2956
modified_store = self.get_store(self)
2922
2957
sections = list(modified_store.get_sections())
2923
2958
self.assertLength(0, sections)
2930
2965
'branch.conf is *always* created when a branch is initialized')
2931
2966
store = self.get_store(self)
2932
2967
store._load_from_string('foo=bar\n')
2933
self.assertEquals(False, self.has_store(store))
2968
self.assertEqual(False, self.has_store(store))
2935
self.assertEquals(True, self.has_store(store))
2970
self.assertEqual(True, self.has_store(store))
2936
2971
modified_store = self.get_store(self)
2937
2972
sections = list(modified_store.get_sections())
2938
2973
self.assertLength(1, sections)
2951
2991
def test_set_option_in_default_section(self):
2952
2992
store = self.get_store(self)
2953
2993
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)
2954
2999
section = store.get_mutable_section(None)
2955
3000
section.set('foo', 'bar')
2962
3007
def test_set_option_in_named_section(self):
2963
3008
store = self.get_store(self)
2964
3009
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)
2965
3015
section = store.get_mutable_section('baz')
2966
3016
section.set('foo', 'bar')
2971
3021
self.assertSectionContent(('baz', {'foo': 'bar'}), sections[0])
2973
3023
def test_load_hook(self):
2974
# We first needs to ensure that the store exists
3024
# First, we need to ensure that the store exists
2975
3025
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)
2976
3031
section = store.get_mutable_section('baz')
2977
3032
section.set('foo', 'bar')
2994
3049
config.ConfigHooks.install_named_hook('save', hook, None)
2995
3050
self.assertLength(0, calls)
2996
3051
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)
2997
3057
section = store.get_mutable_section('baz')
2998
3058
section.set('foo', 'bar')
3000
3060
self.assertLength(1, calls)
3001
self.assertEquals((store,), calls[0])
3061
self.assertEqual((store,), calls[0])
3003
3063
def test_set_mark_dirty(self):
3004
3064
stack = config.MemoryStack('')
3052
3112
s2.set('baz', 'quux')
3053
3113
s1.store.save()
3054
3114
# Changes don't propagate magically
3055
self.assertEquals(None, s1.get('baz'))
3115
self.assertEqual(None, s1.get('baz'))
3056
3116
s2.store.save_changes()
3057
self.assertEquals('quux', s2.get('baz'))
3117
self.assertEqual('quux', s2.get('baz'))
3058
3118
# Changes are acquired when saving
3059
self.assertEquals('bar', s2.get('foo'))
3119
self.assertEqual('bar', s2.get('foo'))
3060
3120
# Since there is no overlap, no warnings are emitted
3061
3121
self.assertLength(0, self.warnings)
3124
3184
def test_invalid_content(self):
3125
3185
store = config.TransportIniFileStore(self.get_transport(), 'foo.conf')
3126
self.assertEquals(False, store.is_loaded())
3186
self.assertEqual(False, store.is_loaded())
3127
3187
exc = self.assertRaises(
3128
3188
errors.ParseConfigError, store._load_from_string,
3129
3189
'this is invalid !')
3130
3190
self.assertEndsWith(exc.filename, 'foo.conf')
3131
3191
# And the load failed
3132
self.assertEquals(False, store.is_loaded())
3192
self.assertEqual(False, store.is_loaded())
3134
3194
def test_get_embedded_sections(self):
3135
3195
# A more complicated example (which also shows that section names and
3202
3262
self.stack.store.save()
3204
3264
def test_simple_read_access(self):
3205
self.assertEquals('1', self.stack.get('one'))
3265
self.assertEqual('1', self.stack.get('one'))
3207
3267
def test_simple_write_access(self):
3208
3268
self.stack.set('one', 'one')
3209
self.assertEquals('one', self.stack.get('one'))
3269
self.assertEqual('one', self.stack.get('one'))
3211
3271
def test_listen_to_the_last_speaker(self):
3212
3272
c1 = self.stack
3213
3273
c2 = self.get_stack(self)
3214
3274
c1.set('one', 'ONE')
3215
3275
c2.set('two', 'TWO')
3216
self.assertEquals('ONE', c1.get('one'))
3217
self.assertEquals('TWO', c2.get('two'))
3276
self.assertEqual('ONE', c1.get('one'))
3277
self.assertEqual('TWO', c2.get('two'))
3218
3278
# The second update respect the first one
3219
self.assertEquals('ONE', c2.get('one'))
3279
self.assertEqual('ONE', c2.get('one'))
3221
3281
def test_last_speaker_wins(self):
3222
3282
# If the same config is not shared, the same variable modified twice
3225
3285
c2 = self.get_stack(self)
3226
3286
c1.set('one', 'c1')
3227
3287
c2.set('one', 'c2')
3228
self.assertEquals('c2', c2.get('one'))
3288
self.assertEqual('c2', c2.get('one'))
3229
3289
# The first modification is still available until another refresh
3231
self.assertEquals('c1', c1.get('one'))
3291
self.assertEqual('c1', c1.get('one'))
3232
3292
c1.set('two', 'done')
3233
self.assertEquals('c2', c1.get('one'))
3293
self.assertEqual('c2', c1.get('one'))
3235
3295
def test_writes_are_serialized(self):
3236
3296
c1 = self.stack
3294
3354
# Ensure the thread is ready to write
3295
3355
ready_to_write.wait()
3296
self.assertEquals('c1', c1.get('one'))
3356
self.assertEqual('c1', c1.get('one'))
3297
3357
# If we read during the write, we get the old value
3298
3358
c2 = self.get_stack(self)
3299
self.assertEquals('1', c2.get('one'))
3359
self.assertEqual('1', c2.get('one'))
3300
3360
# Let the writing occur and ensure it occurred
3301
3361
do_writing.set()
3302
3362
writing_done.wait()
3303
3363
# Now we get the updated value
3304
3364
c3 = self.get_stack(self)
3305
self.assertEquals('c1', c3.get('one'))
3365
self.assertEqual('c1', c3.get('one'))
3307
3367
# FIXME: It may be worth looking into removing the lock dir when it's not
3308
3368
# needed anymore and look at possible fallouts for concurrent lockers. This
3324
3384
store = self.get_store(self)
3325
3385
store._load_from_string('')
3326
3386
matcher = self.matcher(store, '/bar')
3327
self.assertEquals([], list(matcher.get_sections()))
3387
self.assertEqual([], list(matcher.get_sections()))
3329
3389
def test_build_doesnt_load_store(self):
3330
3390
store = self.get_store(self)
3331
matcher = self.matcher(store, '/bar')
3391
self.matcher(store, '/bar')
3332
3392
self.assertFalse(store.is_loaded())
3341
3401
def test_simple_option(self):
3342
3402
section = self.get_section({'foo': 'bar'}, '')
3343
self.assertEquals('bar', section.get('foo'))
3403
self.assertEqual('bar', section.get('foo'))
3345
3405
def test_option_with_extra_path(self):
3346
3406
section = self.get_section({'foo': 'bar', 'foo:policy': 'appendpath'},
3348
self.assertEquals('bar/baz', section.get('foo'))
3408
self.assertEqual('bar/baz', section.get('foo'))
3350
3410
def test_invalid_policy(self):
3351
3411
section = self.get_section({'foo': 'bar', 'foo:policy': 'die'},
3353
3413
# invalid policies are ignored
3354
self.assertEquals('bar', section.get('foo'))
3414
self.assertEqual('bar', section.get('foo'))
3357
3417
class TestLocationMatcher(TestStore):
3376
3436
section=/quux/quux
3378
self.assertEquals(['/foo', '/foo/baz', '/foo/bar', '/foo/bar/baz',
3438
self.assertEqual(['/foo', '/foo/baz', '/foo/bar', '/foo/bar/baz',
3380
3440
[section.id for _, section in store.get_sections()])
3381
3441
matcher = config.LocationMatcher(store, '/foo/bar/quux')
3382
3442
sections = [section for _, section in matcher.get_sections()]
3383
self.assertEquals(['/foo/bar', '/foo'],
3443
self.assertEqual(['/foo/bar', '/foo'],
3384
3444
[section.id for section in sections])
3385
self.assertEquals(['quux', 'bar/quux'],
3445
self.assertEqual(['quux', 'bar/quux'],
3386
3446
[section.extra_path for section in sections])
3388
3448
def test_more_specific_sections_first(self):
3394
3454
section=/foo/bar
3396
self.assertEquals(['/foo', '/foo/bar'],
3456
self.assertEqual(['/foo', '/foo/bar'],
3397
3457
[section.id for _, section in store.get_sections()])
3398
3458
matcher = config.LocationMatcher(store, '/foo/bar/baz')
3399
3459
sections = [section for _, section in matcher.get_sections()]
3400
self.assertEquals(['/foo/bar', '/foo'],
3460
self.assertEqual(['/foo/bar', '/foo'],
3401
3461
[section.id for section in sections])
3402
self.assertEquals(['baz', 'bar/baz'],
3462
self.assertEqual(['baz', 'bar/baz'],
3403
3463
[section.extra_path for section in sections])
3405
3465
def test_appendpath_in_no_name_section(self):
3424
3484
expected_url = 'file:///dir/subdir'
3425
3485
expected_location = '/dir/subdir'
3426
3486
matcher = config.LocationMatcher(store, expected_url)
3427
self.assertEquals(expected_location, matcher.location)
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'])
3430
3512
class TestStartingPathMatcher(TestStore):
3448
3530
def test_url_vs_local_paths(self):
3449
3531
# The matcher location is an url and the section names are local paths
3450
sections = self.assertSectionIDs(['/foo/bar', '/foo'],
3451
'file:///foo/bar/baz', '''\
3532
self.assertSectionIDs(['/foo/bar', '/foo'],
3533
'file:///foo/bar/baz', '''\
3456
3538
def test_local_path_vs_url(self):
3457
3539
# The matcher location is a local path and the section names are urls
3458
sections = self.assertSectionIDs(['file:///foo/bar', 'file:///foo'],
3459
'/foo/bar/baz', '''\
3540
self.assertSectionIDs(['file:///foo/bar', 'file:///foo'],
3541
'/foo/bar/baz', '''\
3461
3543
[file:///foo/bar]
3498
3580
# Note that 'baz' as a relpath for /foo/b* is not fully correct, but
3499
3581
# nothing really is... as far using {relpath} to append it to something
3500
3582
# else, this seems good enough though.
3501
self.assertEquals(['', 'baz', 'bar/baz'],
3583
self.assertEqual(['', 'baz', 'bar/baz'],
3502
3584
[s.locals['relpath'] for _, s in sections])
3504
3586
def test_respect_order(self):
3554
3636
store2 = config.IniFileStore()
3555
3637
store2._load_from_string('foo=baz')
3556
3638
conf = config.Stack([store1.get_sections, store2.get_sections])
3557
self.assertEquals('bar', conf.get('foo'))
3639
self.assertEqual('bar', conf.get('foo'))
3559
3641
def test_get_with_registered_default_value(self):
3560
3642
config.option_registry.register(config.Option('foo', default='bar'))
3561
3643
conf_stack = config.Stack([])
3562
self.assertEquals('bar', conf_stack.get('foo'))
3644
self.assertEqual('bar', conf_stack.get('foo'))
3564
3646
def test_get_without_registered_default_value(self):
3565
3647
config.option_registry.register(config.Option('foo'))
3566
3648
conf_stack = config.Stack([])
3567
self.assertEquals(None, conf_stack.get('foo'))
3649
self.assertEqual(None, conf_stack.get('foo'))
3569
3651
def test_get_without_default_value_for_not_registered(self):
3570
3652
conf_stack = config.Stack([])
3571
self.assertEquals(None, conf_stack.get('foo'))
3653
self.assertEqual(None, conf_stack.get('foo'))
3573
3655
def test_get_for_empty_section_callable(self):
3574
3656
conf_stack = config.Stack([lambda : []])
3575
self.assertEquals(None, conf_stack.get('foo'))
3657
self.assertEqual(None, conf_stack.get('foo'))
3577
3659
def test_get_for_broken_callable(self):
3578
3660
# Trying to use and invalid callable raises an exception on first use
3591
3673
return config.MemoryStack(content)
3593
3675
def test_override_value_from_env(self):
3676
self.overrideEnv('FOO', None)
3594
3677
self.registry.register(
3595
3678
config.Option('foo', default='bar', override_from_env=['FOO']))
3596
3679
self.overrideEnv('FOO', 'quux')
3597
3680
# Env variable provides a default taking over the option one
3598
3681
conf = self.get_conf('foo=store')
3599
self.assertEquals('quux', conf.get('foo'))
3682
self.assertEqual('quux', conf.get('foo'))
3601
3684
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)
3602
3688
self.registry.register(
3603
3689
config.Option('foo', default='bar',
3604
3690
override_from_env=['NO_VALUE', 'FOO', 'BAZ']))
3606
3692
self.overrideEnv('BAZ', 'baz')
3607
3693
# The first env var set wins
3608
3694
conf = self.get_conf('foo=store')
3609
self.assertEquals('foo', conf.get('foo'))
3695
self.assertEqual('foo', conf.get('foo'))
3612
3698
class TestMemoryStack(tests.TestCase):
3614
3700
def test_get(self):
3615
3701
conf = config.MemoryStack('foo=bar')
3616
self.assertEquals('bar', conf.get('foo'))
3702
self.assertEqual('bar', conf.get('foo'))
3618
3704
def test_set(self):
3619
3705
conf = config.MemoryStack('foo=bar')
3620
3706
conf.set('foo', 'baz')
3621
self.assertEquals('baz', conf.get('foo'))
3707
self.assertEqual('baz', conf.get('foo'))
3623
3709
def test_no_content(self):
3624
3710
conf = config.MemoryStack()
3627
3713
self.assertRaises(NotImplementedError, conf.get, 'foo')
3628
3714
# But a content can still be provided
3629
3715
conf.store._load_from_string('foo=bar')
3630
self.assertEquals('bar', conf.get('foo'))
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])
3633
3754
class TestStackWithTransport(tests.TestCaseWithTransport):
3660
3781
config.ConfigHooks.install_named_hook('get', hook, None)
3661
3782
self.assertLength(0, calls)
3662
3783
value = self.conf.get('foo')
3663
self.assertEquals('bar', value)
3784
self.assertEqual('bar', value)
3664
3785
self.assertLength(1, calls)
3665
self.assertEquals((self.conf, 'foo', 'bar'), calls[0])
3786
self.assertEqual((self.conf, 'foo', 'bar'), calls[0])
3668
3789
class TestStackGetWithConverter(tests.TestCase):
3684
3805
def test_get_default_bool_None(self):
3685
3806
self.register_bool_option('foo')
3686
3807
conf = self.get_conf('')
3687
self.assertEquals(None, conf.get('foo'))
3808
self.assertEqual(None, conf.get('foo'))
3689
3810
def test_get_default_bool_True(self):
3690
3811
self.register_bool_option('foo', u'True')
3691
3812
conf = self.get_conf('')
3692
self.assertEquals(True, conf.get('foo'))
3813
self.assertEqual(True, conf.get('foo'))
3694
3815
def test_get_default_bool_False(self):
3695
3816
self.register_bool_option('foo', False)
3696
3817
conf = self.get_conf('')
3697
self.assertEquals(False, conf.get('foo'))
3818
self.assertEqual(False, conf.get('foo'))
3699
3820
def test_get_default_bool_False_as_string(self):
3700
3821
self.register_bool_option('foo', u'False')
3701
3822
conf = self.get_conf('')
3702
self.assertEquals(False, conf.get('foo'))
3823
self.assertEqual(False, conf.get('foo'))
3704
3825
def test_get_default_bool_from_env_converted(self):
3705
3826
self.register_bool_option('foo', u'True', default_from_env=['FOO'])
3706
3827
self.overrideEnv('FOO', 'False')
3707
3828
conf = self.get_conf('')
3708
self.assertEquals(False, conf.get('foo'))
3829
self.assertEqual(False, conf.get('foo'))
3710
3831
def test_get_default_bool_when_conversion_fails(self):
3711
3832
self.register_bool_option('foo', default='True')
3712
3833
conf = self.get_conf('foo=invalid boolean')
3713
self.assertEquals(True, conf.get('foo'))
3834
self.assertEqual(True, conf.get('foo'))
3715
3836
def register_integer_option(self, name,
3716
3837
default=None, default_from_env=None):
3722
3843
def test_get_default_integer_None(self):
3723
3844
self.register_integer_option('foo')
3724
3845
conf = self.get_conf('')
3725
self.assertEquals(None, conf.get('foo'))
3846
self.assertEqual(None, conf.get('foo'))
3727
3848
def test_get_default_integer(self):
3728
3849
self.register_integer_option('foo', 42)
3729
3850
conf = self.get_conf('')
3730
self.assertEquals(42, conf.get('foo'))
3851
self.assertEqual(42, conf.get('foo'))
3732
3853
def test_get_default_integer_as_string(self):
3733
3854
self.register_integer_option('foo', u'42')
3734
3855
conf = self.get_conf('')
3735
self.assertEquals(42, conf.get('foo'))
3856
self.assertEqual(42, conf.get('foo'))
3737
3858
def test_get_default_integer_from_env(self):
3738
3859
self.register_integer_option('foo', default_from_env=['FOO'])
3739
3860
self.overrideEnv('FOO', '18')
3740
3861
conf = self.get_conf('')
3741
self.assertEquals(18, conf.get('foo'))
3862
self.assertEqual(18, conf.get('foo'))
3743
3864
def test_get_default_integer_when_conversion_fails(self):
3744
3865
self.register_integer_option('foo', default='12')
3745
3866
conf = self.get_conf('foo=invalid integer')
3746
self.assertEquals(12, conf.get('foo'))
3867
self.assertEqual(12, conf.get('foo'))
3748
3869
def register_list_option(self, name, default=None, default_from_env=None):
3749
3870
l = config.ListOption(name, help='A list.', default=default,
3753
3874
def test_get_default_list_None(self):
3754
3875
self.register_list_option('foo')
3755
3876
conf = self.get_conf('')
3756
self.assertEquals(None, conf.get('foo'))
3877
self.assertEqual(None, conf.get('foo'))
3758
3879
def test_get_default_list_empty(self):
3759
3880
self.register_list_option('foo', '')
3760
3881
conf = self.get_conf('')
3761
self.assertEquals([], conf.get('foo'))
3882
self.assertEqual([], conf.get('foo'))
3763
3884
def test_get_default_list_from_env(self):
3764
3885
self.register_list_option('foo', default_from_env=['FOO'])
3765
3886
self.overrideEnv('FOO', '')
3766
3887
conf = self.get_conf('')
3767
self.assertEquals([], conf.get('foo'))
3888
self.assertEqual([], conf.get('foo'))
3769
3890
def test_get_with_list_converter_no_item(self):
3770
3891
self.register_list_option('foo', None)
3771
3892
conf = self.get_conf('foo=,')
3772
self.assertEquals([], conf.get('foo'))
3893
self.assertEqual([], conf.get('foo'))
3774
3895
def test_get_with_list_converter_many_items(self):
3775
3896
self.register_list_option('foo', None)
3776
3897
conf = self.get_conf('foo=m,o,r,e')
3777
self.assertEquals(['m', 'o', 'r', 'e'], conf.get('foo'))
3898
self.assertEqual(['m', 'o', 'r', 'e'], conf.get('foo'))
3779
3900
def test_get_with_list_converter_embedded_spaces_many_items(self):
3780
3901
self.register_list_option('foo', None)
3781
3902
conf = self.get_conf('foo=" bar", "baz "')
3782
self.assertEquals([' bar', 'baz '], conf.get('foo'))
3903
self.assertEqual([' bar', 'baz '], conf.get('foo'))
3784
3905
def test_get_with_list_converter_stripped_spaces_many_items(self):
3785
3906
self.register_list_option('foo', None)
3786
3907
conf = self.get_conf('foo= bar , baz ')
3787
self.assertEquals(['bar', 'baz'], conf.get('foo'))
3908
self.assertEqual(['bar', 'baz'], conf.get('foo'))
3790
3911
class TestIterOptionRefs(tests.TestCase):
3791
3912
"""iter_option_refs is a bit unusual, document some cases."""
3793
3914
def assertRefs(self, expected, string):
3794
self.assertEquals(expected, list(config.iter_option_refs(string)))
3915
self.assertEqual(expected, list(config.iter_option_refs(string)))
3796
3917
def test_empty(self):
3797
3918
self.assertRefs([(False, '')], '')
3825
3946
super(TestStackExpandOptions, self).setUp()
3826
3947
self.overrideAttr(config, 'option_registry', config.OptionRegistry())
3827
3948
self.registry = config.option_registry
3828
self.conf = build_branch_stack(self)
3949
store = config.TransportIniFileStore(self.get_transport(), 'foo.conf')
3950
self.conf = config.Stack([store.get_sections], store)
3830
3952
def assertExpansion(self, expected, string, env=None):
3831
self.assertEquals(expected, self.conf.expand_options(string, env))
3953
self.assertEqual(expected, self.conf.expand_options(string, env))
3833
3955
def test_no_expansion(self):
3834
3956
self.assertExpansion('foo', 'foo')
3836
3958
def test_expand_default_value(self):
3837
3959
self.conf.store._load_from_string('bar=baz')
3838
3960
self.registry.register(config.Option('foo', default=u'{bar}'))
3839
self.assertEquals('baz', self.conf.get('foo', expand=True))
3961
self.assertEqual('baz', self.conf.get('foo', expand=True))
3841
3963
def test_expand_default_from_env(self):
3842
3964
self.conf.store._load_from_string('bar=baz')
3843
3965
self.registry.register(config.Option('foo', default_from_env=['FOO']))
3844
3966
self.overrideEnv('FOO', '{bar}')
3845
self.assertEquals('baz', self.conf.get('foo', expand=True))
3967
self.assertEqual('baz', self.conf.get('foo', expand=True))
3847
3969
def test_expand_default_on_failed_conversion(self):
3848
3970
self.conf.store._load_from_string('baz=bogus\nbar=42\nfoo={baz}')
3849
3971
self.registry.register(
3850
3972
config.Option('foo', default=u'{bar}',
3851
3973
from_unicode=config.int_from_store))
3852
self.assertEquals(42, self.conf.get('foo', expand=True))
3974
self.assertEqual(42, self.conf.get('foo', expand=True))
3854
3976
def test_env_adding_options(self):
3855
3977
self.assertExpansion('bar', '{foo}', {'foo': 'bar'})
3866
3988
self.assertRaises(errors.ExpandingUnknownOption,
3867
3989
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}')
3869
3996
def test_indirect_ref(self):
3870
3997
self.conf.store._load_from_string('''
3917
self.registry.register(
3918
config.ListOption('list'))
3919
self.assertEquals(['start', 'middle', 'end'],
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'],
3920
4050
self.conf.get('list', expand=True))
3922
4052
def test_pathologically_hidden_list(self):
4007
4137
stack = config.LocationStack('/home/user/project/')
4008
self.assertEquals('', stack.get('base', expand=True))
4009
self.assertEquals('', stack.get('rel', expand=True))
4138
self.assertEqual('', stack.get('base', expand=True))
4139
self.assertEqual('', stack.get('rel', expand=True))
4011
4141
def test_expand_basename_locally(self):
4012
4142
l_store = config.LocationStore()
4067
4197
stack = config.LocationStack('/home/user/project/branch')
4068
self.assertEquals('glob-bar', stack.get('lbar', expand=True))
4069
self.assertEquals('loc-foo/branch', stack.get('gfoo', expand=True))
4198
self.assertEqual('glob-bar', stack.get('lbar', expand=True))
4199
self.assertEqual('loc-foo/branch', stack.get('gfoo', expand=True))
4071
4201
def test_locals_dont_leak(self):
4072
4202
"""Make sure we chose the right local in presence of several sections.
4091
4221
def test_simple_set(self):
4092
4222
conf = self.get_stack(self)
4093
self.assertEquals(None, conf.get('foo'))
4223
self.assertEqual(None, conf.get('foo'))
4094
4224
conf.set('foo', 'baz')
4095
4225
# Did we get it back ?
4096
self.assertEquals('baz', conf.get('foo'))
4226
self.assertEqual('baz', conf.get('foo'))
4098
4228
def test_set_creates_a_new_section(self):
4099
4229
conf = self.get_stack(self)
4100
4230
conf.set('foo', 'baz')
4101
self.assertEquals, 'baz', conf.get('foo')
4231
self.assertEqual, 'baz', conf.get('foo')
4103
4233
def test_set_hook(self):
4303
4442
user = credentials['user']
4304
4443
password = credentials['password']
4305
self.assertEquals(expected_user, user)
4306
self.assertEquals(expected_password, password)
4444
self.assertEqual(expected_user, user)
4445
self.assertEqual(expected_password, password)
4308
4447
def test_empty_config(self):
4309
4448
conf = config.AuthenticationConfig(_file=StringIO())
4310
self.assertEquals({}, conf._get_config())
4449
self.assertEqual({}, conf._get_config())
4311
4450
self._got_user_passwd(None, None, conf, 'http', 'foo.net')
4313
4452
def test_non_utf8_config(self):
4510
4649
port=99, path='/foo',
4512
4651
CREDENTIALS = {'name': 'name', 'user': 'user', 'password': 'password',
4513
'verify_certificates': False, 'scheme': 'scheme',
4514
'host': 'host', 'port': 99, 'path': '/foo',
4652
'verify_certificates': False, 'scheme': 'scheme',
4653
'host': 'host', 'port': 99, 'path': '/foo',
4515
4654
'realm': 'realm'}
4516
4655
self.assertEqual(CREDENTIALS, credentials)
4517
4656
credentials_from_disk = config.AuthenticationConfig().get_credentials(
4525
4664
self.assertIs(None, conf._get_config().get('name'))
4526
4665
credentials = conf.get_credentials(host='host', scheme='scheme')
4527
4666
CREDENTIALS = {'name': 'name2', 'user': 'user2', 'password':
4528
'password', 'verify_certificates': True,
4529
'scheme': 'scheme', 'host': 'host', 'port': None,
4667
'password', 'verify_certificates': True,
4668
'scheme': 'scheme', 'host': 'host', 'port': None,
4530
4669
'path': None, 'realm': None}
4531
4670
self.assertEqual(CREDENTIALS, credentials)
4550
4689
stdout=stdout, stderr=stderr)
4551
4690
# We use an empty conf so that the user is always prompted
4552
4691
conf = config.AuthenticationConfig()
4553
self.assertEquals(password,
4692
self.assertEqual(password,
4554
4693
conf.get_password(scheme, host, user, port=port,
4555
4694
realm=realm, path=path))
4556
self.assertEquals(expected_prompt, stderr.getvalue())
4557
self.assertEquals('', stdout.getvalue())
4695
self.assertEqual(expected_prompt, stderr.getvalue())
4696
self.assertEqual('', stdout.getvalue())
4559
4698
def _check_default_username_prompt(self, expected_prompt_format, scheme,
4560
4699
host=None, port=None, realm=None,
4571
4710
stdout=stdout, stderr=stderr)
4572
4711
# We use an empty conf so that the user is always prompted
4573
4712
conf = config.AuthenticationConfig()
4574
self.assertEquals(username, conf.get_user(scheme, host, port=port,
4713
self.assertEqual(username, conf.get_user(scheme, host, port=port,
4575
4714
realm=realm, path=path, ask=True))
4576
self.assertEquals(expected_prompt, stderr.getvalue())
4577
self.assertEquals('', stdout.getvalue())
4715
self.assertEqual(expected_prompt, stderr.getvalue())
4716
self.assertEqual('', stdout.getvalue())
4579
4718
def test_username_defaults_prompts(self):
4580
4719
# HTTP prompts can't be tested here, see test_http.py
4666
4805
config.credential_store_registry.register("stub", store, fallback=True)
4667
4806
conf = config.AuthenticationConfig(_file=StringIO())
4668
4807
creds = conf.get_credentials("http", "example.com")
4669
self.assertEquals("joe", creds["user"])
4670
self.assertEquals("secret", creds["password"])
4808
self.assertEqual("joe", creds["user"])
4809
self.assertEqual("secret", creds["password"])
4673
4812
class StubCredentialStore(config.CredentialStore):
4719
4858
def test_fallback_none_registered(self):
4720
4859
r = config.CredentialStoreRegistry()
4721
self.assertEquals(None,
4860
self.assertEqual(None,
4722
4861
r.get_fallback_credentials("http", "example.com"))
4724
4863
def test_register(self):
4725
4864
r = config.CredentialStoreRegistry()
4726
4865
r.register("stub", StubCredentialStore(), fallback=False)
4727
4866
r.register("another", StubCredentialStore(), fallback=True)
4728
self.assertEquals(["another", "stub"], r.keys())
4867
self.assertEqual(["another", "stub"], r.keys())
4730
4869
def test_register_lazy(self):
4731
4870
r = config.CredentialStoreRegistry()
4732
4871
r.register_lazy("stub", "bzrlib.tests.test_config",
4733
4872
"StubCredentialStore", fallback=False)
4734
self.assertEquals(["stub"], r.keys())
4873
self.assertEqual(["stub"], r.keys())
4735
4874
self.assertIsInstance(r.get_credential_store("stub"),
4736
4875
StubCredentialStore)
4739
4878
r = config.CredentialStoreRegistry()
4740
4879
r.register("stub1", None, fallback=False)
4741
4880
r.register("stub2", None, fallback=True)
4742
self.assertEquals(False, r.is_fallback("stub1"))
4743
self.assertEquals(True, r.is_fallback("stub2"))
4881
self.assertEqual(False, r.is_fallback("stub1"))
4882
self.assertEqual(True, r.is_fallback("stub2"))
4745
4884
def test_no_fallback(self):
4746
4885
r = config.CredentialStoreRegistry()
4747
4886
store = CountingCredentialStore()
4748
4887
r.register("count", store, fallback=False)
4749
self.assertEquals(None,
4888
self.assertEqual(None,
4750
4889
r.get_fallback_credentials("http", "example.com"))
4751
self.assertEquals(0, store._calls)
4890
self.assertEqual(0, store._calls)
4753
4892
def test_fallback_credentials(self):
4754
4893
r = config.CredentialStoreRegistry()
4757
4896
"somebody", "geheim")
4758
4897
r.register("stub", store, fallback=True)
4759
4898
creds = r.get_fallback_credentials("http", "example.com")
4760
self.assertEquals("somebody", creds["user"])
4761
self.assertEquals("geheim", creds["password"])
4899
self.assertEqual("somebody", creds["user"])
4900
self.assertEqual("geheim", creds["password"])
4763
4902
def test_fallback_first_wins(self):
4764
4903
r = config.CredentialStoreRegistry()
4781
4920
r = config.credential_store_registry
4782
4921
plain_text = r.get_credential_store()
4783
4922
decoded = plain_text.decode_password(dict(password='secret'))
4784
self.assertEquals('secret', decoded)
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)
4787
4935
# FIXME: Once we have a way to declare authentication to all test servers, we
4815
4963
self.assertIsNot(None, realname)
4816
4964
self.assertIsNot(None, address)
4818
self.assertEquals((None, None), (realname, 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)
4821
5000
class EmailOptionTests(tests.TestCase):
4825
5004
# BZR_EMAIL takes precedence over EMAIL
4826
5005
self.overrideEnv('BZR_EMAIL', 'jelmer@samba.org')
4827
5006
self.overrideEnv('EMAIL', 'jelmer@apache.org')
4828
self.assertEquals('jelmer@samba.org', conf.get('email'))
5007
self.assertEqual('jelmer@samba.org', conf.get('email'))
4830
5009
def test_default_email_uses_EMAIL(self):
4831
5010
conf = config.MemoryStack('')
4832
5011
self.overrideEnv('BZR_EMAIL', None)
4833
5012
self.overrideEnv('EMAIL', 'jelmer@apache.org')
4834
self.assertEquals('jelmer@apache.org', conf.get('email'))
5013
self.assertEqual('jelmer@apache.org', conf.get('email'))
4836
5015
def test_BZR_EMAIL_overrides(self):
4837
5016
conf = config.MemoryStack('email=jelmer@debian.org')
4838
5017
self.overrideEnv('BZR_EMAIL', 'jelmer@apache.org')
4839
self.assertEquals('jelmer@apache.org', conf.get('email'))
5018
self.assertEqual('jelmer@apache.org', conf.get('email'))
4840
5019
self.overrideEnv('BZR_EMAIL', None)
4841
5020
self.overrideEnv('EMAIL', 'jelmer@samba.org')
4842
self.assertEquals('jelmer@debian.org', conf.get('email'))
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,