~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_config.py

  • Committer: Patch Queue Manager
  • Date: 2013-10-07 17:04:34 UTC
  • mfrom: (6588.1.1 trunk)
  • Revision ID: pqm@pqm.ubuntu.com-20131007170434-mb0ahksmrzsnhi1i
(vila) Stricter checks on configuration option names (Vincent Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""Tests for finding and reading the bzr config file[s]."""
18
18
 
19
 
import base64
20
19
from cStringIO import StringIO
21
20
from textwrap import dedent
22
21
import os
629
628
class TestIniConfigBuilding(TestIniConfig):
630
629
 
631
630
    def test_contructs(self):
632
 
        my_config = config.IniBasedConfig()
 
631
        config.IniBasedConfig()
633
632
 
634
633
    def test_from_fp(self):
635
634
        my_config = config.IniBasedConfig.from_string(sample_config_text)
678
677
 
679
678
    def test_saved_with_content(self):
680
679
        content = 'foo = bar\n'
681
 
        conf = config.IniBasedConfig.from_string(
682
 
            content, file_name='./test.conf', save=True)
 
680
        config.IniBasedConfig.from_string(content, file_name='./test.conf',
 
681
                                          save=True)
683
682
        self.assertFileEqual(content, 'test.conf')
684
683
 
685
684
 
1047
1046
class TestGetConfig(tests.TestCase):
1048
1047
 
1049
1048
    def test_constructs(self):
1050
 
        my_config = config.GlobalConfig()
 
1049
        config.GlobalConfig()
1051
1050
 
1052
1051
    def test_calls_read_filenames(self):
1053
1052
        # replace the class that is constructed, to check its parameters
1065
1064
 
1066
1065
class TestBranchConfig(tests.TestCaseWithTransport):
1067
1066
 
1068
 
    def test_constructs(self):
 
1067
    def test_constructs_valid(self):
1069
1068
        branch = FakeBranch()
1070
1069
        my_config = config.BranchConfig(branch)
 
1070
        self.assertIsNot(None, my_config)
 
1071
 
 
1072
    def test_constructs_error(self):
1071
1073
        self.assertRaises(TypeError, config.BranchConfig)
1072
1074
 
1073
1075
    def test_get_location_config(self):
1105
1107
        conf = config.LocationConfig.from_string(
1106
1108
            '[%s]\nnickname = foobar' % (local_url,),
1107
1109
            local_url, save=True)
 
1110
        self.assertIsNot(None, conf)
1108
1111
        self.assertEqual('foobar', branch.nick)
1109
1112
 
1110
1113
    def test_config_local_path(self):
1113
1116
        self.assertEqual('branch', branch.nick)
1114
1117
 
1115
1118
        local_path = osutils.getcwd().encode('utf8')
1116
 
        conf = config.LocationConfig.from_string(
 
1119
        config.LocationConfig.from_string(
1117
1120
            '[%s/branch]\nnickname = barry' % (local_path,),
1118
1121
            'branch',  save=True)
 
1122
        # Now the branch will find its nick via the location config
1119
1123
        self.assertEqual('barry', branch.nick)
1120
1124
 
1121
1125
    def test_config_creates_local(self):
1369
1373
 
1370
1374
class TestLocationConfig(tests.TestCaseInTempDir, TestOptionsMixin):
1371
1375
 
1372
 
    def test_constructs(self):
1373
 
        my_config = config.LocationConfig('http://example.com')
 
1376
    def test_constructs_valid(self):
 
1377
        config.LocationConfig('http://example.com')
 
1378
 
 
1379
    def test_constructs_error(self):
1374
1380
        self.assertRaises(TypeError, config.LocationConfig)
1375
1381
 
1376
1382
    def test_branch_calls_read_filenames(self):
1662
1668
        if location_config is None:
1663
1669
            location_config = sample_branches_text
1664
1670
 
1665
 
        my_global_config = config.GlobalConfig.from_string(global_config,
1666
 
                                                           save=True)
1667
 
        my_location_config = config.LocationConfig.from_string(
1668
 
            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,
 
1673
                                          save=True)
1669
1674
        my_config = config.BranchConfig(my_branch)
1670
1675
        self.my_config = my_config
1671
1676
        self.my_location_config = my_config._get_location_config()
1736
1741
                          location_config=None, branch_data_config=None):
1737
1742
        my_branch = FakeBranch(location)
1738
1743
        if global_config is not None:
1739
 
            my_global_config = config.GlobalConfig.from_string(global_config,
1740
 
                                                               save=True)
 
1744
            config.GlobalConfig.from_string(global_config, save=True)
1741
1745
        if location_config is not None:
1742
 
            my_location_config = config.LocationConfig.from_string(
1743
 
                location_config, my_branch.base, save=True)
 
1746
            config.LocationConfig.from_string(location_config, my_branch.base,
 
1747
                                              save=True)
1744
1748
        my_config = config.BranchConfig(my_branch)
1745
1749
        if branch_data_config is not None:
1746
1750
            my_config.branch.control_files.files['branch.conf'] = \
2220
2224
        self.assertSaveHook(remote_bzrdir._get_config())
2221
2225
 
2222
2226
 
 
2227
class TestOptionNames(tests.TestCase):
 
2228
 
 
2229
    def is_valid(self, name):
 
2230
        return config._option_ref_re.match('{%s}' % name) is not None
 
2231
 
 
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
 
 
2241
    def test_invalid_names(self):
 
2242
        self.assertFalse(self.is_valid(' foo'))
 
2243
        self.assertFalse(self.is_valid('foo '))
 
2244
        self.assertFalse(self.is_valid('1'))
 
2245
        self.assertFalse(self.is_valid('1,2'))
 
2246
        self.assertFalse(self.is_valid('foo$'))
 
2247
        self.assertFalse(self.is_valid('!foo'))
 
2248
        self.assertFalse(self.is_valid('foo.'))
 
2249
        self.assertFalse(self.is_valid('foo..bar'))
 
2250
        self.assertFalse(self.is_valid('{}'))
 
2251
        self.assertFalse(self.is_valid('{a}'))
 
2252
        self.assertFalse(self.is_valid('a\n'))
 
2253
 
 
2254
    def assertSingleGroup(self, reference):
 
2255
        # the regexp is used with split and as such should match the reference
 
2256
        # *only*, if more groups needs to be defined, (?:...) should be used.
 
2257
        m = config._option_ref_re.match('{a}')
 
2258
        self.assertLength(1, m.groups())
 
2259
 
 
2260
    def test_valid_references(self):
 
2261
        self.assertSingleGroup('{a}')
 
2262
        self.assertSingleGroup('{{a}}')
 
2263
 
 
2264
 
2223
2265
class TestOption(tests.TestCase):
2224
2266
 
2225
2267
    def test_default_value(self):
2447
2489
        self.registry.register(opt)
2448
2490
        self.assertEquals('A simple option', self.registry.get_help('foo'))
2449
2491
 
 
2492
    def test_dont_register_illegal_name(self):
 
2493
        self.assertRaises(errors.IllegalOptionName,
 
2494
                          self.registry.register, config.Option(' foo'))
 
2495
        self.assertRaises(errors.IllegalOptionName,
 
2496
                          self.registry.register, config.Option('bar,'))
 
2497
 
2450
2498
    lazy_option = config.Option('lazy_foo', help='Lazy help')
2451
2499
 
2452
2500
    def test_register_lazy(self):
2459
2507
                                    'TestOptionRegistry.lazy_option')
2460
2508
        self.assertEquals('Lazy help', self.registry.get_help('lazy_foo'))
2461
2509
 
 
2510
    def test_dont_lazy_register_illegal_name(self):
 
2511
        # This is where the root cause of http://pad.lv/1235099 is better
 
2512
        # understood: 'register_lazy' doc string mentions that key should match
 
2513
        # the option name which indirectly requires that the option name is a
 
2514
        # valid python identifier. We violate that rule here (using a key that
 
2515
        # doesn't match the option name) to test the option name checking.
 
2516
        self.assertRaises(errors.IllegalOptionName,
 
2517
                          self.registry.register_lazy, ' foo', self.__module__,
 
2518
                          'TestOptionRegistry.lazy_option')
 
2519
        self.assertRaises(errors.IllegalOptionName,
 
2520
                          self.registry.register_lazy, '1,2', self.__module__,
 
2521
                          'TestOptionRegistry.lazy_option')
 
2522
 
2462
2523
 
2463
2524
class TestRegisteredOptions(tests.TestCase):
2464
2525
    """All registered options should verify some constraints."""
3320
3381
 
3321
3382
    def test_build_doesnt_load_store(self):
3322
3383
        store = self.get_store(self)
3323
 
        matcher = self.matcher(store, '/bar')
 
3384
        self.matcher(store, '/bar')
3324
3385
        self.assertFalse(store.is_loaded())
3325
3386
 
3326
3387
 
3461
3522
 
3462
3523
    def test_url_vs_local_paths(self):
3463
3524
        # The matcher location is an url and the section names are local paths
3464
 
        sections = self.assertSectionIDs(['/foo/bar', '/foo'],
3465
 
                                         'file:///foo/bar/baz', '''\
 
3525
        self.assertSectionIDs(['/foo/bar', '/foo'],
 
3526
                              'file:///foo/bar/baz', '''\
3466
3527
[/foo]
3467
3528
[/foo/bar]
3468
3529
''')
3469
3530
 
3470
3531
    def test_local_path_vs_url(self):
3471
3532
        # The matcher location is a local path and the section names are urls
3472
 
        sections = self.assertSectionIDs(['file:///foo/bar', 'file:///foo'],
3473
 
                                         '/foo/bar/baz', '''\
 
3533
        self.assertSectionIDs(['file:///foo/bar', 'file:///foo'],
 
3534
                              '/foo/bar/baz', '''\
3474
3535
[file:///foo]
3475
3536
[file:///foo/bar]
3476
3537
''')
3693
3754
 
3694
3755
    def test_build_stack(self):
3695
3756
        # Just a smoke test to help debug builders
3696
 
        stack = self.get_stack(self)
 
3757
        self.get_stack(self)
3697
3758
 
3698
3759
 
3699
3760
class TestStackGet(TestStackWithTransport):
3920
3981
        self.assertRaises(errors.ExpandingUnknownOption,
3921
3982
                          self.conf.expand_options, '{foo}')
3922
3983
 
 
3984
    def test_illegal_def_is_ignored(self):
 
3985
        self.assertExpansion('{1,2}', '{1,2}')
 
3986
        self.assertExpansion('{ }', '{ }')
 
3987
        self.assertExpansion('${Foo,f}', '${Foo,f}')
 
3988
 
3923
3989
    def test_indirect_ref(self):
3924
3990
        self.conf.store._load_from_string('''
3925
3991
foo=xxx
4297
4363
        """
4298
4364
        sections = list(conf._get_sections(name))
4299
4365
        self.assertLength(len(expected), sections)
4300
 
        self.assertEqual(expected, [name for name, _, _ in sections])
 
4366
        self.assertEqual(expected, [n for n, _, _ in sections])
4301
4367
 
4302
4368
    def test_bazaar_default_section(self):
4303
4369
        self.assertSectionNames(['DEFAULT'], self.bazaar_config)