~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_config.py

Move all features to bzrlib.tests.features in 2.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
    ui,
38
38
    urlutils,
39
39
    registry,
 
40
    remote,
40
41
    tests,
41
42
    trace,
42
43
    transport,
45
46
    deprecated_in,
46
47
    deprecated_method,
47
48
    )
48
 
from bzrlib.transport import remote
 
49
from bzrlib.transport import remote as transport_remote
49
50
from bzrlib.tests import (
50
51
    features,
51
 
    TestSkipped,
52
52
    scenarios,
 
53
    test_server,
53
54
    )
54
55
from bzrlib.util.configobj import configobj
55
56
 
118
119
def build_remote_branch_store(test):
119
120
    # There is only one permutation (but we won't be able to handle more with
120
121
    # this design anyway)
121
 
    (transport_class, server_class) = remote.get_test_permutations()[0]
 
122
    (transport_class,
 
123
     server_class) = transport_remote.get_test_permutations()[0]
122
124
    build_backing_branch(test, 'branch', transport_class, server_class)
123
125
    b = branch.Branch.open(test.get_url('branch'))
124
126
    return config.BranchStore(b)
142
144
def build_remote_branch_stack(test):
143
145
    # There is only one permutation (but we won't be able to handle more with
144
146
    # this design anyway)
145
 
    (transport_class, server_class) = remote.get_test_permutations()[0]
 
147
    (transport_class,
 
148
     server_class) = transport_remote.get_test_permutations()[0]
146
149
    build_backing_branch(test, 'branch', transport_class, server_class)
147
150
    b = branch.Branch.open(test.get_url('branch'))
148
151
    return config.BranchStack(b)
158
161
change_editor=vimdiff -of @new_path @old_path
159
162
gpg_signing_command=gnome-gpg
160
163
log_format=short
 
164
validate_signatures_in_log=true
 
165
acceptable_keys=amy
161
166
user_global_option=something
162
167
bzr.mergetool.sometool=sometool {base} {this} {other} -o {result}
163
168
bzr.mergetool.funkytool=funkytool "arg with spaces" {this_temp}
510
515
        my_config = config.Config()
511
516
        self.assertEqual('long', my_config.log_format())
512
517
 
 
518
    def test_acceptable_keys_default(self):
 
519
        my_config = config.Config()
 
520
        self.assertEqual(None, my_config.acceptable_keys())
 
521
 
 
522
    def test_validate_signatures_in_log_default(self):
 
523
        my_config = config.Config()
 
524
        self.assertEqual(False, my_config.validate_signatures_in_log())
 
525
 
513
526
    def test_get_change_editor(self):
514
527
        my_config = InstrumentedConfig()
515
528
        change_editor = my_config.get_change_editor('old_tree', 'new_tree')
1237
1250
        my_config = self._get_sample_config()
1238
1251
        self.assertEqual("short", my_config.log_format())
1239
1252
 
 
1253
    def test_configured_acceptable_keys(self):
 
1254
        my_config = self._get_sample_config()
 
1255
        self.assertEqual("amy", my_config.acceptable_keys())
 
1256
 
 
1257
    def test_configured_validate_signatures_in_log(self):
 
1258
        my_config = self._get_sample_config()
 
1259
        self.assertEqual(True, my_config.validate_signatures_in_log())
 
1260
 
1240
1261
    def test_get_alias(self):
1241
1262
        my_config = self._get_sample_config()
1242
1263
        self.assertEqual('help', my_config.get_alias('h'))
1868
1889
 
1869
1890
class TestTransportConfig(tests.TestCaseWithTransport):
1870
1891
 
 
1892
    def test_load_utf8(self):
 
1893
        """Ensure we can load an utf8-encoded file."""
 
1894
        t = self.get_transport()
 
1895
        unicode_user = u'b\N{Euro Sign}ar'
 
1896
        unicode_content = u'user=%s' % (unicode_user,)
 
1897
        utf8_content = unicode_content.encode('utf8')
 
1898
        # Store the raw content in the config file
 
1899
        t.put_bytes('foo.conf', utf8_content)
 
1900
        conf = config.TransportConfig(t, 'foo.conf')
 
1901
        self.assertEquals(unicode_user, conf.get_option('user'))
 
1902
 
 
1903
    def test_load_non_ascii(self):
 
1904
        """Ensure we display a proper error on non-ascii, non utf-8 content."""
 
1905
        t = self.get_transport()
 
1906
        t.put_bytes('foo.conf', 'user=foo\n#\xff\n')
 
1907
        conf = config.TransportConfig(t, 'foo.conf')
 
1908
        self.assertRaises(errors.ConfigContentError, conf._get_configobj)
 
1909
 
 
1910
    def test_load_erroneous_content(self):
 
1911
        """Ensure we display a proper error on content that can't be parsed."""
 
1912
        t = self.get_transport()
 
1913
        t.put_bytes('foo.conf', '[open_section\n')
 
1914
        conf = config.TransportConfig(t, 'foo.conf')
 
1915
        self.assertRaises(errors.ParseConfigError, conf._get_configobj)
 
1916
 
1871
1917
    def test_get_value(self):
1872
1918
        """Test that retreiving a value from a section is possible"""
1873
 
        bzrdir_config = config.TransportConfig(transport.get_transport('.'),
 
1919
        bzrdir_config = config.TransportConfig(self.get_transport('.'),
1874
1920
                                               'control.conf')
1875
1921
        bzrdir_config.set_option('value', 'key', 'SECTION')
1876
1922
        bzrdir_config.set_option('value2', 'key2')
1906
1952
        self.assertIs(None, bzrdir_config.get_default_stack_on())
1907
1953
 
1908
1954
 
 
1955
class TestOldConfigHooks(tests.TestCaseWithTransport):
 
1956
 
 
1957
    def setUp(self):
 
1958
        super(TestOldConfigHooks, self).setUp()
 
1959
        create_configs_with_file_option(self)
 
1960
 
 
1961
    def assertGetHook(self, conf, name, value):
 
1962
        calls = []
 
1963
        def hook(*args):
 
1964
            calls.append(args)
 
1965
        config.OldConfigHooks.install_named_hook('get', hook, None)
 
1966
        self.addCleanup(
 
1967
            config.OldConfigHooks.uninstall_named_hook, 'get', None)
 
1968
        self.assertLength(0, calls)
 
1969
        actual_value = conf.get_user_option(name)
 
1970
        self.assertEquals(value, actual_value)
 
1971
        self.assertLength(1, calls)
 
1972
        self.assertEquals((conf, name, value), calls[0])
 
1973
 
 
1974
    def test_get_hook_bazaar(self):
 
1975
        self.assertGetHook(self.bazaar_config, 'file', 'bazaar')
 
1976
 
 
1977
    def test_get_hook_locations(self):
 
1978
        self.assertGetHook(self.locations_config, 'file', 'locations')
 
1979
 
 
1980
    def test_get_hook_branch(self):
 
1981
        # Since locations masks branch, we define a different option
 
1982
        self.branch_config.set_user_option('file2', 'branch')
 
1983
        self.assertGetHook(self.branch_config, 'file2', 'branch')
 
1984
 
 
1985
    def assertSetHook(self, conf, name, value):
 
1986
        calls = []
 
1987
        def hook(*args):
 
1988
            calls.append(args)
 
1989
        config.OldConfigHooks.install_named_hook('set', hook, None)
 
1990
        self.addCleanup(
 
1991
            config.OldConfigHooks.uninstall_named_hook, 'set', None)
 
1992
        self.assertLength(0, calls)
 
1993
        conf.set_user_option(name, value)
 
1994
        self.assertLength(1, calls)
 
1995
        # We can't assert the conf object below as different configs use
 
1996
        # different means to implement set_user_option and we care only about
 
1997
        # coverage here.
 
1998
        self.assertEquals((name, value), calls[0][1:])
 
1999
 
 
2000
    def test_set_hook_bazaar(self):
 
2001
        self.assertSetHook(self.bazaar_config, 'foo', 'bazaar')
 
2002
 
 
2003
    def test_set_hook_locations(self):
 
2004
        self.assertSetHook(self.locations_config, 'foo', 'locations')
 
2005
 
 
2006
    def test_set_hook_branch(self):
 
2007
        self.assertSetHook(self.branch_config, 'foo', 'branch')
 
2008
 
 
2009
    def assertRemoveHook(self, conf, name, section_name=None):
 
2010
        calls = []
 
2011
        def hook(*args):
 
2012
            calls.append(args)
 
2013
        config.OldConfigHooks.install_named_hook('remove', hook, None)
 
2014
        self.addCleanup(
 
2015
            config.OldConfigHooks.uninstall_named_hook, 'remove', None)
 
2016
        self.assertLength(0, calls)
 
2017
        conf.remove_user_option(name, section_name)
 
2018
        self.assertLength(1, calls)
 
2019
        # We can't assert the conf object below as different configs use
 
2020
        # different means to implement remove_user_option and we care only about
 
2021
        # coverage here.
 
2022
        self.assertEquals((name,), calls[0][1:])
 
2023
 
 
2024
    def test_remove_hook_bazaar(self):
 
2025
        self.assertRemoveHook(self.bazaar_config, 'file')
 
2026
 
 
2027
    def test_remove_hook_locations(self):
 
2028
        self.assertRemoveHook(self.locations_config, 'file',
 
2029
                              self.locations_config.location)
 
2030
 
 
2031
    def test_remove_hook_branch(self):
 
2032
        self.assertRemoveHook(self.branch_config, 'file')
 
2033
 
 
2034
    def assertLoadHook(self, name, conf_class, *conf_args):
 
2035
        calls = []
 
2036
        def hook(*args):
 
2037
            calls.append(args)
 
2038
        config.OldConfigHooks.install_named_hook('load', hook, None)
 
2039
        self.addCleanup(
 
2040
            config.OldConfigHooks.uninstall_named_hook, 'load', None)
 
2041
        self.assertLength(0, calls)
 
2042
        # Build a config
 
2043
        conf = conf_class(*conf_args)
 
2044
        # Access an option to trigger a load
 
2045
        conf.get_user_option(name)
 
2046
        self.assertLength(1, calls)
 
2047
        # Since we can't assert about conf, we just use the number of calls ;-/
 
2048
 
 
2049
    def test_load_hook_bazaar(self):
 
2050
        self.assertLoadHook('file', config.GlobalConfig)
 
2051
 
 
2052
    def test_load_hook_locations(self):
 
2053
        self.assertLoadHook('file', config.LocationConfig, self.tree.basedir)
 
2054
 
 
2055
    def test_load_hook_branch(self):
 
2056
        self.assertLoadHook('file', config.BranchConfig, self.tree.branch)
 
2057
 
 
2058
    def assertSaveHook(self, conf):
 
2059
        calls = []
 
2060
        def hook(*args):
 
2061
            calls.append(args)
 
2062
        config.OldConfigHooks.install_named_hook('save', hook, None)
 
2063
        self.addCleanup(
 
2064
            config.OldConfigHooks.uninstall_named_hook, 'save', None)
 
2065
        self.assertLength(0, calls)
 
2066
        # Setting an option triggers a save
 
2067
        conf.set_user_option('foo', 'bar')
 
2068
        self.assertLength(1, calls)
 
2069
        # Since we can't assert about conf, we just use the number of calls ;-/
 
2070
 
 
2071
    def test_save_hook_bazaar(self):
 
2072
        self.assertSaveHook(self.bazaar_config)
 
2073
 
 
2074
    def test_save_hook_locations(self):
 
2075
        self.assertSaveHook(self.locations_config)
 
2076
 
 
2077
    def test_save_hook_branch(self):
 
2078
        self.assertSaveHook(self.branch_config)
 
2079
 
 
2080
 
 
2081
class TestOldConfigHooksForRemote(tests.TestCaseWithTransport):
 
2082
    """Tests config hooks for remote configs.
 
2083
 
 
2084
    No tests for the remove hook as this is not implemented there.
 
2085
    """
 
2086
 
 
2087
    def setUp(self):
 
2088
        super(TestOldConfigHooksForRemote, self).setUp()
 
2089
        self.transport_server = test_server.SmartTCPServer_for_testing
 
2090
        create_configs_with_file_option(self)
 
2091
 
 
2092
    def assertGetHook(self, conf, name, value):
 
2093
        calls = []
 
2094
        def hook(*args):
 
2095
            calls.append(args)
 
2096
        config.OldConfigHooks.install_named_hook('get', hook, None)
 
2097
        self.addCleanup(
 
2098
            config.OldConfigHooks.uninstall_named_hook, 'get', None)
 
2099
        self.assertLength(0, calls)
 
2100
        actual_value = conf.get_option(name)
 
2101
        self.assertEquals(value, actual_value)
 
2102
        self.assertLength(1, calls)
 
2103
        self.assertEquals((conf, name, value), calls[0])
 
2104
 
 
2105
    def test_get_hook_remote_branch(self):
 
2106
        remote_branch = branch.Branch.open(self.get_url('tree'))
 
2107
        self.assertGetHook(remote_branch._get_config(), 'file', 'branch')
 
2108
 
 
2109
    def test_get_hook_remote_bzrdir(self):
 
2110
        remote_bzrdir = bzrdir.BzrDir.open(self.get_url('tree'))
 
2111
        conf = remote_bzrdir._get_config()
 
2112
        conf.set_option('remotedir', 'file')
 
2113
        self.assertGetHook(conf, 'file', 'remotedir')
 
2114
 
 
2115
    def assertSetHook(self, conf, name, value):
 
2116
        calls = []
 
2117
        def hook(*args):
 
2118
            calls.append(args)
 
2119
        config.OldConfigHooks.install_named_hook('set', hook, None)
 
2120
        self.addCleanup(
 
2121
            config.OldConfigHooks.uninstall_named_hook, 'set', None)
 
2122
        self.assertLength(0, calls)
 
2123
        conf.set_option(value, name)
 
2124
        self.assertLength(1, calls)
 
2125
        # We can't assert the conf object below as different configs use
 
2126
        # different means to implement set_user_option and we care only about
 
2127
        # coverage here.
 
2128
        self.assertEquals((name, value), calls[0][1:])
 
2129
 
 
2130
    def test_set_hook_remote_branch(self):
 
2131
        remote_branch = branch.Branch.open(self.get_url('tree'))
 
2132
        self.addCleanup(remote_branch.lock_write().unlock)
 
2133
        self.assertSetHook(remote_branch._get_config(), 'file', 'remote')
 
2134
 
 
2135
    def test_set_hook_remote_bzrdir(self):
 
2136
        remote_branch = branch.Branch.open(self.get_url('tree'))
 
2137
        self.addCleanup(remote_branch.lock_write().unlock)
 
2138
        remote_bzrdir = bzrdir.BzrDir.open(self.get_url('tree'))
 
2139
        self.assertSetHook(remote_bzrdir._get_config(), 'file', 'remotedir')
 
2140
 
 
2141
    def assertLoadHook(self, expected_nb_calls, name, conf_class, *conf_args):
 
2142
        calls = []
 
2143
        def hook(*args):
 
2144
            calls.append(args)
 
2145
        config.OldConfigHooks.install_named_hook('load', hook, None)
 
2146
        self.addCleanup(
 
2147
            config.OldConfigHooks.uninstall_named_hook, 'load', None)
 
2148
        self.assertLength(0, calls)
 
2149
        # Build a config
 
2150
        conf = conf_class(*conf_args)
 
2151
        # Access an option to trigger a load
 
2152
        conf.get_option(name)
 
2153
        self.assertLength(expected_nb_calls, calls)
 
2154
        # Since we can't assert about conf, we just use the number of calls ;-/
 
2155
 
 
2156
    def test_load_hook_remote_branch(self):
 
2157
        remote_branch = branch.Branch.open(self.get_url('tree'))
 
2158
        self.assertLoadHook(1, 'file', remote.RemoteBranchConfig, remote_branch)
 
2159
 
 
2160
    def test_load_hook_remote_bzrdir(self):
 
2161
        remote_bzrdir = bzrdir.BzrDir.open(self.get_url('tree'))
 
2162
        # The config file doesn't exist, set an option to force its creation
 
2163
        conf = remote_bzrdir._get_config()
 
2164
        conf.set_option('remotedir', 'file')
 
2165
        # We get one call for the server and one call for the client, this is
 
2166
        # caused by the differences in implementations betwen
 
2167
        # SmartServerBzrDirRequestConfigFile (in smart/bzrdir.py) and
 
2168
        # SmartServerBranchGetConfigFile (in smart/branch.py)
 
2169
        self.assertLoadHook(2 ,'file', remote.RemoteBzrDirConfig, remote_bzrdir)
 
2170
 
 
2171
    def assertSaveHook(self, conf):
 
2172
        calls = []
 
2173
        def hook(*args):
 
2174
            calls.append(args)
 
2175
        config.OldConfigHooks.install_named_hook('save', hook, None)
 
2176
        self.addCleanup(
 
2177
            config.OldConfigHooks.uninstall_named_hook, 'save', None)
 
2178
        self.assertLength(0, calls)
 
2179
        # Setting an option triggers a save
 
2180
        conf.set_option('foo', 'bar')
 
2181
        self.assertLength(1, calls)
 
2182
        # Since we can't assert about conf, we just use the number of calls ;-/
 
2183
 
 
2184
    def test_save_hook_remote_branch(self):
 
2185
        remote_branch = branch.Branch.open(self.get_url('tree'))
 
2186
        self.addCleanup(remote_branch.lock_write().unlock)
 
2187
        self.assertSaveHook(remote_branch._get_config())
 
2188
 
 
2189
    def test_save_hook_remote_bzrdir(self):
 
2190
        remote_branch = branch.Branch.open(self.get_url('tree'))
 
2191
        self.addCleanup(remote_branch.lock_write().unlock)
 
2192
        remote_bzrdir = bzrdir.BzrDir.open(self.get_url('tree'))
 
2193
        self.assertSaveHook(remote_bzrdir._get_config())
 
2194
 
 
2195
 
1909
2196
class TestOption(tests.TestCase):
1910
2197
 
1911
2198
    def test_default_value(self):
2084
2371
        self.assertRaises(AssertionError, store._load_from_string, 'bar=baz')
2085
2372
 
2086
2373
 
 
2374
class TestIniFileStoreContent(tests.TestCaseWithTransport):
 
2375
    """Simulate loading a config store without content of various encodings.
 
2376
 
 
2377
    All files produced by bzr are in utf8 content.
 
2378
 
 
2379
    Users may modify them manually and end up with a file that can't be
 
2380
    loaded. We need to issue proper error messages in this case.
 
2381
    """
 
2382
 
 
2383
    invalid_utf8_char = '\xff'
 
2384
 
 
2385
    def test_load_utf8(self):
 
2386
        """Ensure we can load an utf8-encoded file."""
 
2387
        t = self.get_transport()
 
2388
        # From http://pad.lv/799212
 
2389
        unicode_user = u'b\N{Euro Sign}ar'
 
2390
        unicode_content = u'user=%s' % (unicode_user,)
 
2391
        utf8_content = unicode_content.encode('utf8')
 
2392
        # Store the raw content in the config file
 
2393
        t.put_bytes('foo.conf', utf8_content)
 
2394
        store = config.IniFileStore(t, 'foo.conf')
 
2395
        store.load()
 
2396
        stack = config.Stack([store.get_sections], store)
 
2397
        self.assertEquals(unicode_user, stack.get('user'))
 
2398
 
 
2399
    def test_load_non_ascii(self):
 
2400
        """Ensure we display a proper error on non-ascii, non utf-8 content."""
 
2401
        t = self.get_transport()
 
2402
        t.put_bytes('foo.conf', 'user=foo\n#%s\n' % (self.invalid_utf8_char,))
 
2403
        store = config.IniFileStore(t, 'foo.conf')
 
2404
        self.assertRaises(errors.ConfigContentError, store.load)
 
2405
 
 
2406
    def test_load_erroneous_content(self):
 
2407
        """Ensure we display a proper error on content that can't be parsed."""
 
2408
        t = self.get_transport()
 
2409
        t.put_bytes('foo.conf', '[open_section\n')
 
2410
        store = config.IniFileStore(t, 'foo.conf')
 
2411
        self.assertRaises(errors.ParseConfigError, store.load)
 
2412
 
 
2413
 
 
2414
class TestIniConfigContent(tests.TestCaseWithTransport):
 
2415
    """Simulate loading a IniBasedConfig without content of various encodings.
 
2416
 
 
2417
    All files produced by bzr are in utf8 content.
 
2418
 
 
2419
    Users may modify them manually and end up with a file that can't be
 
2420
    loaded. We need to issue proper error messages in this case.
 
2421
    """
 
2422
 
 
2423
    invalid_utf8_char = '\xff'
 
2424
 
 
2425
    def test_load_utf8(self):
 
2426
        """Ensure we can load an utf8-encoded file."""
 
2427
        # From http://pad.lv/799212
 
2428
        unicode_user = u'b\N{Euro Sign}ar'
 
2429
        unicode_content = u'user=%s' % (unicode_user,)
 
2430
        utf8_content = unicode_content.encode('utf8')
 
2431
        # Store the raw content in the config file
 
2432
        with open('foo.conf', 'wb') as f:
 
2433
            f.write(utf8_content)
 
2434
        conf = config.IniBasedConfig(file_name='foo.conf')
 
2435
        self.assertEquals(unicode_user, conf.get_user_option('user'))
 
2436
 
 
2437
    def test_load_badly_encoded_content(self):
 
2438
        """Ensure we display a proper error on non-ascii, non utf-8 content."""
 
2439
        with open('foo.conf', 'wb') as f:
 
2440
            f.write('user=foo\n#%s\n' % (self.invalid_utf8_char,))
 
2441
        conf = config.IniBasedConfig(file_name='foo.conf')
 
2442
        self.assertRaises(errors.ConfigContentError, conf._get_parser)
 
2443
 
 
2444
    def test_load_erroneous_content(self):
 
2445
        """Ensure we display a proper error on content that can't be parsed."""
 
2446
        with open('foo.conf', 'wb') as f:
 
2447
            f.write('[open_section\n')
 
2448
        conf = config.IniBasedConfig(file_name='foo.conf')
 
2449
        self.assertRaises(errors.ParseConfigError, conf._get_parser)
 
2450
 
 
2451
 
2087
2452
class TestMutableStore(TestStore):
2088
2453
 
2089
2454
    scenarios = [(key, {'store_id': key, 'get_store': builder}) for key, builder
2167
2532
        self.assertLength(1, sections)
2168
2533
        self.assertSectionContent(('baz', {'foo': 'bar'}), sections[0])
2169
2534
 
 
2535
    def test_load_hook(self):
 
2536
        # We first needs to ensure that the store exists
 
2537
        store = self.get_store(self)
 
2538
        section = store.get_mutable_section('baz')
 
2539
        section.set('foo', 'bar')
 
2540
        store.save()
 
2541
        # Now we can try to load it
 
2542
        store = self.get_store(self)
 
2543
        calls = []
 
2544
        def hook(*args):
 
2545
            calls.append(args)
 
2546
        config.ConfigHooks.install_named_hook('load', hook, None)
 
2547
        self.assertLength(0, calls)
 
2548
        store.load()
 
2549
        self.assertLength(1, calls)
 
2550
        self.assertEquals((store,), calls[0])
 
2551
 
 
2552
    def test_save_hook(self):
 
2553
        calls = []
 
2554
        def hook(*args):
 
2555
            calls.append(args)
 
2556
        config.ConfigHooks.install_named_hook('save', hook, None)
 
2557
        self.assertLength(0, calls)
 
2558
        store = self.get_store(self)
 
2559
        section = store.get_mutable_section('baz')
 
2560
        section.set('foo', 'bar')
 
2561
        store.save()
 
2562
        self.assertLength(1, calls)
 
2563
        self.assertEquals((store,), calls[0])
 
2564
 
2170
2565
 
2171
2566
class TestIniFileStore(TestStore):
2172
2567
 
2494
2889
        conf_stack = config.Stack([conf1, conf2])
2495
2890
        self.assertEquals('baz', conf_stack.get('foo'))
2496
2891
 
2497
 
    def test_get_for_empty_stack(self):
2498
 
        conf_stack = config.Stack([])
2499
 
        self.assertEquals(None, conf_stack.get('foo'))
2500
 
 
2501
2892
    def test_get_for_empty_section_callable(self):
2502
2893
        conf_stack = config.Stack([lambda : []])
2503
2894
        self.assertEquals(None, conf_stack.get('foo'))
2521
2912
        stack = self.get_stack(self)
2522
2913
 
2523
2914
 
 
2915
class TestStackGet(TestStackWithTransport):
 
2916
 
 
2917
    def test_get_for_empty_stack(self):
 
2918
        conf = self.get_stack(self)
 
2919
        self.assertEquals(None, conf.get('foo'))
 
2920
 
 
2921
    def test_get_hook(self):
 
2922
        conf = self.get_stack(self)
 
2923
        conf.store._load_from_string('foo=bar')
 
2924
        calls = []
 
2925
        def hook(*args):
 
2926
            calls.append(args)
 
2927
        config.ConfigHooks.install_named_hook('get', hook, None)
 
2928
        self.assertLength(0, calls)
 
2929
        value = conf.get('foo')
 
2930
        self.assertEquals('bar', value)
 
2931
        self.assertLength(1, calls)
 
2932
        self.assertEquals((conf, 'foo', 'bar'), calls[0])
 
2933
 
 
2934
 
2524
2935
class TestStackSet(TestStackWithTransport):
2525
2936
 
2526
2937
    def test_simple_set(self):
2536
2947
        conf.set('foo', 'baz')
2537
2948
        self.assertEquals, 'baz', conf.get('foo')
2538
2949
 
 
2950
    def test_set_hook(self):
 
2951
        calls = []
 
2952
        def hook(*args):
 
2953
            calls.append(args)
 
2954
        config.ConfigHooks.install_named_hook('set', hook, None)
 
2955
        self.assertLength(0, calls)
 
2956
        conf = self.get_stack(self)
 
2957
        conf.set('foo', 'bar')
 
2958
        self.assertLength(1, calls)
 
2959
        self.assertEquals((conf, 'foo', 'bar'), calls[0])
 
2960
 
2539
2961
 
2540
2962
class TestStackRemove(TestStackWithTransport):
2541
2963
 
2551
2973
        conf = self.get_stack(self)
2552
2974
        self.assertRaises(KeyError, conf.remove, 'I_do_not_exist')
2553
2975
 
 
2976
    def test_remove_hook(self):
 
2977
        calls = []
 
2978
        def hook(*args):
 
2979
            calls.append(args)
 
2980
        config.ConfigHooks.install_named_hook('remove', hook, None)
 
2981
        self.assertLength(0, calls)
 
2982
        conf = self.get_stack(self)
 
2983
        conf.store._load_from_string('foo=bar')
 
2984
        conf.remove('foo')
 
2985
        self.assertLength(1, calls)
 
2986
        self.assertEquals((conf, 'foo'), calls[0])
 
2987
 
2554
2988
 
2555
2989
class TestConfigGetOptions(tests.TestCaseWithTransport, TestOptionsMixin):
2556
2990
 
2723
3157
        self.assertEquals({}, conf._get_config())
2724
3158
        self._got_user_passwd(None, None, conf, 'http', 'foo.net')
2725
3159
 
 
3160
    def test_non_utf8_config(self):
 
3161
        conf = config.AuthenticationConfig(_file=StringIO(
 
3162
                'foo = bar\xff'))
 
3163
        self.assertRaises(errors.ConfigContentError, conf._get_config)
 
3164
        
2726
3165
    def test_missing_auth_section_header(self):
2727
3166
        conf = config.AuthenticationConfig(_file=StringIO('foo = bar'))
2728
3167
        self.assertRaises(ValueError, conf.get_credentials, 'ftp', 'foo.net')
3216
3655
        to be able to choose a user name with no configuration.
3217
3656
        """
3218
3657
        if sys.platform == 'win32':
3219
 
            raise TestSkipped("User name inference not implemented on win32")
 
3658
            raise tests.TestSkipped(
 
3659
                "User name inference not implemented on win32")
3220
3660
        realname, address = config._auto_user_id()
3221
3661
        if os.path.exists('/etc/mailname'):
3222
3662
            self.assertIsNot(None, realname)