/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
4449.3.30 by Martin Pool
Tweaks to test_config ui factory use
1
# Copyright (C) 2005, 2006, 2008, 2009 Canonical Ltd
1442.1.1 by Robert Collins
move config_dir into bzrlib.config
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1442.1.1 by Robert Collins
move config_dir into bzrlib.config
16
17
"""Tests for finding and reading the bzr config file[s]."""
18
# import system imports here
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
19
from cStringIO import StringIO
1442.1.1 by Robert Collins
move config_dir into bzrlib.config
20
import os
21
import sys
22
23
#import bzrlib specific imports here
1878.1.3 by John Arbash Meinel
some test cleanups
24
from bzrlib import (
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
25
    branch,
26
    bzrdir,
1878.1.3 by John Arbash Meinel
some test cleanups
27
    config,
28
    errors,
29
    osutils,
2681.1.8 by Aaron Bentley
Add Thunderbird support to bzr send
30
    mail_client,
2900.2.14 by Vincent Ladeuil
More tests.
31
    ui,
1878.1.3 by John Arbash Meinel
some test cleanups
32
    urlutils,
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
33
    tests,
1551.15.35 by Aaron Bentley
Warn when setting config values that will be masked (#122286)
34
    trace,
3242.1.2 by Aaron Bentley
Turn BzrDirConfig into TransportConfig, reduce code duplication
35
    transport,
1878.1.3 by John Arbash Meinel
some test cleanups
36
    )
2991.2.4 by Vincent Ladeuil
Various fixes following local testing environment rebuild.
37
from bzrlib.util.configobj import configobj
1442.1.1 by Robert Collins
move config_dir into bzrlib.config
38
39
1553.6.12 by Erik Bågfors
remove AliasConfig, based on input from abentley
40
sample_long_alias="log -r-15..-1 --line"
2120.6.2 by James Henstridge
remove get_matching_sections() norecurse tests, since that feature is handled in the config policy code now
41
sample_config_text = u"""
42
[DEFAULT]
43
email=Erik B\u00e5gfors <erik@bagfors.nu>
44
editor=vim
45
gpg_signing_command=gnome-gpg
46
log_format=short
47
user_global_option=something
48
[ALIASES]
49
h=help
50
ll=""" + sample_long_alias + "\n"
51
52
53
sample_always_signatures = """
54
[DEFAULT]
55
check_signatures=ignore
56
create_signatures=always
57
"""
58
59
sample_ignore_signatures = """
60
[DEFAULT]
61
check_signatures=require
62
create_signatures=never
63
"""
64
65
sample_maybe_signatures = """
66
[DEFAULT]
67
check_signatures=ignore
68
create_signatures=when-required
69
"""
70
71
sample_branches_text = """
72
[http://www.example.com]
73
# Top level policy
74
email=Robert Collins <robertc@example.org>
2120.6.3 by James Henstridge
add some more tests for getting policy options, and behaviour of get_user_option in the presence of config policies
75
normal_option = normal
76
appendpath_option = append
2120.6.8 by James Henstridge
Change syntax for setting config option policies. Rather than
77
appendpath_option:policy = appendpath
2120.6.3 by James Henstridge
add some more tests for getting policy options, and behaviour of get_user_option in the presence of config policies
78
norecurse_option = norecurse
2120.6.8 by James Henstridge
Change syntax for setting config option policies. Rather than
79
norecurse_option:policy = norecurse
2120.6.2 by James Henstridge
remove get_matching_sections() norecurse tests, since that feature is handled in the config policy code now
80
[http://www.example.com/ignoreparent]
81
# different project: ignore parent dir config
82
ignore_parents=true
83
[http://www.example.com/norecurse]
84
# configuration items that only apply to this dir
85
recurse=false
2120.6.3 by James Henstridge
add some more tests for getting policy options, and behaviour of get_user_option in the presence of config policies
86
normal_option = norecurse
87
[http://www.example.com/dir]
88
appendpath_option = normal
2120.6.2 by James Henstridge
remove get_matching_sections() norecurse tests, since that feature is handled in the config policy code now
89
[/b/]
90
check_signatures=require
91
# test trailing / matching with no children
92
[/a/]
93
check_signatures=check-available
94
gpg_signing_command=false
95
user_local_option=local
96
# test trailing / matching
97
[/a/*]
98
#subdirs will match but not the parent
99
[/a/c]
100
check_signatures=ignore
101
post_commit=bzrlib.tests.test_config.post_commit
102
#testing explicit beats globs
103
"""
1553.6.3 by Erik Bågfors
tests for AliasesConfig
104
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
105
1474 by Robert Collins
Merge from Aaron Bentley.
106
class InstrumentedConfigObj(object):
107
    """A config obj look-enough-alike to record calls made to it."""
108
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
109
    def __contains__(self, thing):
110
        self._calls.append(('__contains__', thing))
111
        return False
112
113
    def __getitem__(self, key):
114
        self._calls.append(('__getitem__', key))
115
        return self
116
1551.2.20 by Aaron Bentley
Treated config files as utf-8
117
    def __init__(self, input, encoding=None):
118
        self._calls = [('__init__', input, encoding)]
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
119
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
120
    def __setitem__(self, key, value):
121
        self._calls.append(('__setitem__', key, value))
122
2120.6.4 by James Henstridge
add support for specifying policy when storing options
123
    def __delitem__(self, key):
124
        self._calls.append(('__delitem__', key))
125
126
    def keys(self):
127
        self._calls.append(('keys',))
128
        return []
129
1551.2.49 by abentley
Made ConfigObj output binary-identical files on win32 and *nix
130
    def write(self, arg):
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
131
        self._calls.append(('write',))
132
2120.6.4 by James Henstridge
add support for specifying policy when storing options
133
    def as_bool(self, value):
134
        self._calls.append(('as_bool', value))
135
        return False
136
137
    def get_value(self, section, name):
138
        self._calls.append(('get_value', section, name))
139
        return None
140
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
141
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
142
class FakeBranch(object):
143
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
144
    def __init__(self, base=None, user_id=None):
145
        if base is None:
146
            self.base = "http://example.com/branches/demo"
147
        else:
148
            self.base = base
3407.2.13 by Martin Pool
Remove indirection through control_files to get transports
149
        self._transport = self.control_files = \
150
            FakeControlFilesAndTransport(user_id=user_id)
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
151
4226.1.7 by Robert Collins
Alter test_config.FakeBranch in accordance with the Branch change to have a _get_config.
152
    def _get_config(self):
153
        return config.TransportConfig(self._transport, 'branch.conf')
154
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
155
    def lock_write(self):
156
        pass
157
158
    def unlock(self):
159
        pass
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
160
161
3407.2.13 by Martin Pool
Remove indirection through control_files to get transports
162
class FakeControlFilesAndTransport(object):
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
163
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
164
    def __init__(self, user_id=None):
165
        self.files = {}
3388.2.3 by Martin Pool
Fix up more uses of LockableFiles.get_utf8 in tests
166
        if user_id:
167
            self.files['email'] = user_id
3242.1.2 by Aaron Bentley
Turn BzrDirConfig into TransportConfig, reduce code duplication
168
        self._transport = self
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
169
1185.65.29 by Robert Collins
Implement final review suggestions.
170
    def get_utf8(self, filename):
3388.2.3 by Martin Pool
Fix up more uses of LockableFiles.get_utf8 in tests
171
        # from LockableFiles
172
        raise AssertionError("get_utf8 should no longer be used")
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
173
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
174
    def get(self, filename):
3388.2.3 by Martin Pool
Fix up more uses of LockableFiles.get_utf8 in tests
175
        # from Transport
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
176
        try:
177
            return StringIO(self.files[filename])
178
        except KeyError:
179
            raise errors.NoSuchFile(filename)
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
180
3388.2.3 by Martin Pool
Fix up more uses of LockableFiles.get_utf8 in tests
181
    def get_bytes(self, filename):
182
        # from Transport
183
        try:
184
            return self.files[filename]
185
        except KeyError:
186
            raise errors.NoSuchFile(filename)
187
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
188
    def put(self, filename, fileobj):
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
189
        self.files[filename] = fileobj.read()
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
190
3242.1.2 by Aaron Bentley
Turn BzrDirConfig into TransportConfig, reduce code duplication
191
    def put_file(self, filename, fileobj):
192
        return self.put(filename, fileobj)
193
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
194
195
class InstrumentedConfig(config.Config):
196
    """An instrumented config that supplies stubs for template methods."""
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
197
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
198
    def __init__(self):
199
        super(InstrumentedConfig, self).__init__()
200
        self._calls = []
1442.1.15 by Robert Collins
make getting the signature checking policy a template method
201
        self._signatures = config.CHECK_NEVER
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
202
203
    def _get_user_id(self):
204
        self._calls.append('_get_user_id')
205
        return "Robert Collins <robert.collins@example.org>"
206
1442.1.15 by Robert Collins
make getting the signature checking policy a template method
207
    def _get_signature_checking(self):
208
        self._calls.append('_get_signature_checking')
209
        return self._signatures
210
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
211
1556.2.2 by Aaron Bentley
Fixed get_bool
212
bool_config = """[DEFAULT]
213
active = true
214
inactive = false
215
[UPPERCASE]
216
active = True
217
nonactive = False
218
"""
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
219
220
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
221
class TestConfigObj(tests.TestCase):
3221.7.4 by Matt Nordhoff
Add test for bug #86838.
222
1556.2.2 by Aaron Bentley
Fixed get_bool
223
    def test_get_bool(self):
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
224
        co = config.ConfigObj(StringIO(bool_config))
1556.2.2 by Aaron Bentley
Fixed get_bool
225
        self.assertIs(co.get_bool('DEFAULT', 'active'), True)
226
        self.assertIs(co.get_bool('DEFAULT', 'inactive'), False)
227
        self.assertIs(co.get_bool('UPPERCASE', 'active'), True)
228
        self.assertIs(co.get_bool('UPPERCASE', 'nonactive'), False)
229
3221.7.4 by Matt Nordhoff
Add test for bug #86838.
230
    def test_hash_sign_in_value(self):
231
        """
232
        Before 4.5.0, ConfigObj did not quote # signs in values, so they'd be
233
        treated as comments when read in again. (#86838)
234
        """
235
        co = config.ConfigObj()
236
        co['test'] = 'foo#bar'
237
        lines = co.write()
238
        self.assertEqual(lines, ['test = "foo#bar"'])
239
        co2 = config.ConfigObj(lines)
240
        self.assertEqual(co2['test'], 'foo#bar')
241
1556.2.2 by Aaron Bentley
Fixed get_bool
242
2900.1.1 by Vincent Ladeuil
243
erroneous_config = """[section] # line 1
244
good=good # line 2
245
[section] # line 3
246
whocares=notme # line 4
247
"""
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
248
249
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
250
class TestConfigObjErrors(tests.TestCase):
2900.1.1 by Vincent Ladeuil
251
252
    def test_duplicate_section_name_error_line(self):
253
        try:
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
254
            co = configobj.ConfigObj(StringIO(erroneous_config),
255
                                     raise_errors=True)
2900.1.1 by Vincent Ladeuil
256
        except config.configobj.DuplicateError, e:
257
            self.assertEqual(3, e.line_number)
258
        else:
259
            self.fail('Error in config file not detected')
260
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
261
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
262
class TestConfig(tests.TestCase):
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
263
264
    def test_constructs(self):
265
        config.Config()
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
266
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
267
    def test_no_default_editor(self):
268
        self.assertRaises(NotImplementedError, config.Config().get_editor)
269
270
    def test_user_email(self):
271
        my_config = InstrumentedConfig()
272
        self.assertEqual('robert.collins@example.org', my_config.user_email())
273
        self.assertEqual(['_get_user_id'], my_config._calls)
274
275
    def test_username(self):
276
        my_config = InstrumentedConfig()
277
        self.assertEqual('Robert Collins <robert.collins@example.org>',
278
                         my_config.username())
279
        self.assertEqual(['_get_user_id'], my_config._calls)
1442.1.14 by Robert Collins
Create a default signature checking policy of CHECK_IF_POSSIBLE
280
281
    def test_signatures_default(self):
282
        my_config = config.Config()
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
283
        self.assertFalse(my_config.signature_needed())
1442.1.14 by Robert Collins
Create a default signature checking policy of CHECK_IF_POSSIBLE
284
        self.assertEqual(config.CHECK_IF_POSSIBLE,
285
                         my_config.signature_checking())
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
286
        self.assertEqual(config.SIGN_WHEN_REQUIRED,
287
                         my_config.signing_policy())
1442.1.14 by Robert Collins
Create a default signature checking policy of CHECK_IF_POSSIBLE
288
1442.1.15 by Robert Collins
make getting the signature checking policy a template method
289
    def test_signatures_template_method(self):
290
        my_config = InstrumentedConfig()
291
        self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
292
        self.assertEqual(['_get_signature_checking'], my_config._calls)
293
294
    def test_signatures_template_method_none(self):
295
        my_config = InstrumentedConfig()
296
        my_config._signatures = None
297
        self.assertEqual(config.CHECK_IF_POSSIBLE,
298
                         my_config.signature_checking())
299
        self.assertEqual(['_get_signature_checking'], my_config._calls)
300
1442.1.56 by Robert Collins
gpg_signing_command configuration item
301
    def test_gpg_signing_command_default(self):
302
        my_config = config.Config()
303
        self.assertEqual('gpg', my_config.gpg_signing_command())
304
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
305
    def test_get_user_option_default(self):
306
        my_config = config.Config()
307
        self.assertEqual(None, my_config.get_user_option('no_option'))
308
1472 by Robert Collins
post commit hook, first pass implementation
309
    def test_post_commit_default(self):
310
        my_config = config.Config()
311
        self.assertEqual(None, my_config.post_commit())
312
1553.2.9 by Erik Bågfors
log_formatter => log_format for "named" formatters
313
    def test_log_format_default(self):
1553.2.8 by Erik Bågfors
tests for config log_formatter
314
        my_config = config.Config()
1553.2.9 by Erik Bågfors
log_formatter => log_format for "named" formatters
315
        self.assertEqual('long', my_config.log_format())
1553.2.8 by Erik Bågfors
tests for config log_formatter
316
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
317
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
318
class TestConfigPath(tests.TestCase):
1442.1.1 by Robert Collins
move config_dir into bzrlib.config
319
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
320
    def setUp(self):
321
        super(TestConfigPath, self).setUp()
322
        os.environ['HOME'] = '/home/bogus'
4584.3.23 by Martin Pool
Correction to xdg_cache_dir and add a simple test
323
        os.environ['XDG_CACHE_DIR'] = ''
2309.2.6 by Alexander Belchenko
bzr now use Win32 API to determine Application Data location, and don't rely solely on $APPDATA
324
        if sys.platform == 'win32':
325
            os.environ['BZR_HOME'] = \
326
                r'C:\Documents and Settings\bogus\Application Data'
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
327
            self.bzr_home = \
328
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0'
329
        else:
330
            self.bzr_home = '/home/bogus/.bazaar'
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
331
1442.1.1 by Robert Collins
move config_dir into bzrlib.config
332
    def test_config_dir(self):
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
333
        self.assertEqual(config.config_dir(), self.bzr_home)
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
334
335
    def test_config_filename(self):
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
336
        self.assertEqual(config.config_filename(),
337
                         self.bzr_home + '/bazaar.conf')
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
338
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
339
    def test_branches_config_filename(self):
2991.2.4 by Vincent Ladeuil
Various fixes following local testing environment rebuild.
340
        self.assertEqual(config.branches_config_filename(),
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
341
                         self.bzr_home + '/branches.conf')
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
342
1770.2.2 by Aaron Bentley
Rename branches.conf to locations.conf
343
    def test_locations_config_filename(self):
2991.2.4 by Vincent Ladeuil
Various fixes following local testing environment rebuild.
344
        self.assertEqual(config.locations_config_filename(),
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
345
                         self.bzr_home + '/locations.conf')
1770.2.2 by Aaron Bentley
Rename branches.conf to locations.conf
346
2900.2.5 by Vincent Ladeuil
ake ftp aware of authentication config.
347
    def test_authentication_config_filename(self):
2991.2.4 by Vincent Ladeuil
Various fixes following local testing environment rebuild.
348
        self.assertEqual(config.authentication_config_filename(),
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
349
                         self.bzr_home + '/authentication.conf')
350
4584.3.23 by Martin Pool
Correction to xdg_cache_dir and add a simple test
351
    def test_xdg_cache_dir(self):
352
        self.assertEqual(config.xdg_cache_dir(),
353
            '/home/bogus/.cache')
354
2900.2.5 by Vincent Ladeuil
ake ftp aware of authentication config.
355
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
356
class TestIniConfig(tests.TestCase):
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
357
358
    def test_contructs(self):
359
        my_config = config.IniBasedConfig("nothing")
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
360
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
361
    def test_from_fp(self):
1551.2.20 by Aaron Bentley
Treated config files as utf-8
362
        config_file = StringIO(sample_config_text.encode('utf-8'))
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
363
        my_config = config.IniBasedConfig(None)
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
364
        self.failUnless(
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
365
            isinstance(my_config._get_parser(file=config_file),
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
366
                        configobj.ConfigObj))
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
367
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
368
    def test_cached(self):
1551.2.20 by Aaron Bentley
Treated config files as utf-8
369
        config_file = StringIO(sample_config_text.encode('utf-8'))
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
370
        my_config = config.IniBasedConfig(None)
371
        parser = my_config._get_parser(file=config_file)
372
        self.failUnless(my_config._get_parser() is parser)
373
4503.2.2 by Vincent Ladeuil
Get a bool or none from a config file.
374
    def test_get_user_option_as_bool(self):
375
        config_file = StringIO("""
376
a_true_bool = true
377
a_false_bool = 0
378
an_invalid_bool = maybe
379
a_list = hmm, who knows ? # This interpreted as a list !
380
""".encode('utf-8'))
381
        my_config = config.IniBasedConfig(None)
382
        parser = my_config._get_parser(file=config_file)
383
        get_option = my_config.get_user_option_as_bool
384
        self.assertEqual(True, get_option('a_true_bool'))
385
        self.assertEqual(False, get_option('a_false_bool'))
386
        self.assertIs(None, get_option('an_invalid_bool'))
387
        self.assertIs(None, get_option('not_defined_in_this_config'))
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
388
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
389
class TestGetConfig(tests.TestCase):
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
390
391
    def test_constructs(self):
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
392
        my_config = config.GlobalConfig()
393
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
394
    def test_calls_read_filenames(self):
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
395
        # replace the class that is constructed, to check its parameters
1474 by Robert Collins
Merge from Aaron Bentley.
396
        oldparserclass = config.ConfigObj
397
        config.ConfigObj = InstrumentedConfigObj
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
398
        my_config = config.GlobalConfig()
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
399
        try:
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
400
            parser = my_config._get_parser()
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
401
        finally:
1474 by Robert Collins
Merge from Aaron Bentley.
402
            config.ConfigObj = oldparserclass
403
        self.failUnless(isinstance(parser, InstrumentedConfigObj))
1551.2.20 by Aaron Bentley
Treated config files as utf-8
404
        self.assertEqual(parser._calls, [('__init__', config.config_filename(),
405
                                          'utf-8')])
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
406
407
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
408
class TestBranchConfig(tests.TestCaseWithTransport):
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
409
410
    def test_constructs(self):
411
        branch = FakeBranch()
412
        my_config = config.BranchConfig(branch)
413
        self.assertRaises(TypeError, config.BranchConfig)
414
415
    def test_get_location_config(self):
416
        branch = FakeBranch()
417
        my_config = config.BranchConfig(branch)
418
        location_config = my_config._get_location_config()
419
        self.assertEqual(branch.base, location_config.location)
420
        self.failUnless(location_config is my_config._get_location_config())
421
1770.2.9 by Aaron Bentley
Add Branch.get_config, update BranchConfig() callers
422
    def test_get_config(self):
423
        """The Branch.get_config method works properly"""
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
424
        b = bzrdir.BzrDir.create_standalone_workingtree('.').branch
1770.2.9 by Aaron Bentley
Add Branch.get_config, update BranchConfig() callers
425
        my_config = b.get_config()
426
        self.assertIs(my_config.get_user_option('wacky'), None)
427
        my_config.set_user_option('wacky', 'unlikely')
428
        self.assertEqual(my_config.get_user_option('wacky'), 'unlikely')
429
430
        # Ensure we get the same thing if we start again
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
431
        b2 = branch.Branch.open('.')
1770.2.9 by Aaron Bentley
Add Branch.get_config, update BranchConfig() callers
432
        my_config2 = b2.get_config()
433
        self.assertEqual(my_config2.get_user_option('wacky'), 'unlikely')
434
1824.1.1 by Robert Collins
Add BranchConfig.has_explicit_nickname call.
435
    def test_has_explicit_nickname(self):
436
        b = self.make_branch('.')
437
        self.assertFalse(b.get_config().has_explicit_nickname())
438
        b.nick = 'foo'
439
        self.assertTrue(b.get_config().has_explicit_nickname())
440
1878.1.1 by John Arbash Meinel
Entries in locations.conf should prefer local paths if available (bug #53653)
441
    def test_config_url(self):
442
        """The Branch.get_config will use section that uses a local url"""
443
        branch = self.make_branch('branch')
444
        self.assertEqual('branch', branch.nick)
445
446
        locations = config.locations_config_filename()
447
        config.ensure_config_dir_exists()
448
        local_url = urlutils.local_path_to_url('branch')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
449
        open(locations, 'wb').write('[%s]\nnickname = foobar'
1878.1.1 by John Arbash Meinel
Entries in locations.conf should prefer local paths if available (bug #53653)
450
                                    % (local_url,))
451
        self.assertEqual('foobar', branch.nick)
452
453
    def test_config_local_path(self):
454
        """The Branch.get_config will use a local system path"""
455
        branch = self.make_branch('branch')
456
        self.assertEqual('branch', branch.nick)
457
458
        locations = config.locations_config_filename()
459
        config.ensure_config_dir_exists()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
460
        open(locations, 'wb').write('[%s/branch]\nnickname = barry'
1878.1.1 by John Arbash Meinel
Entries in locations.conf should prefer local paths if available (bug #53653)
461
                                    % (osutils.getcwd().encode('utf8'),))
462
        self.assertEqual('barry', branch.nick)
463
1878.1.2 by John Arbash Meinel
Add a test that new locations.conf entries are created with a local path, rather than a URL
464
    def test_config_creates_local(self):
465
        """Creating a new entry in config uses a local path."""
2230.3.6 by Aaron Bentley
work in progress bind stuff
466
        branch = self.make_branch('branch', format='knit')
1878.1.2 by John Arbash Meinel
Add a test that new locations.conf entries are created with a local path, rather than a URL
467
        branch.set_push_location('http://foobar')
468
        locations = config.locations_config_filename()
469
        local_path = osutils.getcwd().encode('utf8')
470
        # Surprisingly ConfigObj doesn't create a trailing newline
471
        self.check_file_contents(locations,
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
472
                                 '[%s/branch]\n'
473
                                 'push_location = http://foobar\n'
3221.7.1 by Matt Nordhoff
Upgrade ConfigObj to version 4.5.1.
474
                                 'push_location:policy = norecurse\n'
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
475
                                 % (local_path,))
1878.1.2 by John Arbash Meinel
Add a test that new locations.conf entries are created with a local path, rather than a URL
476
2120.5.4 by Alexander Belchenko
Whitebox test for Config.get_nickname (req. by Aaron Bentley)
477
    def test_autonick_urlencoded(self):
478
        b = self.make_branch('!repo')
479
        self.assertEqual('!repo', b.get_config().get_nickname())
480
1551.15.35 by Aaron Bentley
Warn when setting config values that will be masked (#122286)
481
    def test_warn_if_masked(self):
482
        _warning = trace.warning
483
        warnings = []
484
        def warning(*args):
485
            warnings.append(args[0] % args[1:])
486
487
        def set_option(store, warn_masked=True):
488
            warnings[:] = []
489
            conf.set_user_option('example_option', repr(store), store=store,
490
                                 warn_masked=warn_masked)
491
        def assertWarning(warning):
492
            if warning is None:
493
                self.assertEqual(0, len(warnings))
494
            else:
495
                self.assertEqual(1, len(warnings))
496
                self.assertEqual(warning, warnings[0])
497
        trace.warning = warning
498
        try:
499
            branch = self.make_branch('.')
500
            conf = branch.get_config()
501
            set_option(config.STORE_GLOBAL)
502
            assertWarning(None)
503
            set_option(config.STORE_BRANCH)
504
            assertWarning(None)
505
            set_option(config.STORE_GLOBAL)
506
            assertWarning('Value "4" is masked by "3" from branch.conf')
507
            set_option(config.STORE_GLOBAL, warn_masked=False)
508
            assertWarning(None)
509
            set_option(config.STORE_LOCATION)
510
            assertWarning(None)
511
            set_option(config.STORE_BRANCH)
512
            assertWarning('Value "3" is masked by "0" from locations.conf')
513
            set_option(config.STORE_BRANCH, warn_masked=False)
514
            assertWarning(None)
515
        finally:
516
            trace.warning = _warning
517
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
518
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
519
class TestGlobalConfigItems(tests.TestCase):
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
520
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
521
    def test_user_id(self):
1551.2.20 by Aaron Bentley
Treated config files as utf-8
522
        config_file = StringIO(sample_config_text.encode('utf-8'))
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
523
        my_config = config.GlobalConfig()
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
524
        my_config._parser = my_config._get_parser(file=config_file)
1551.2.21 by Aaron Bentley
Formatted unicode config tests as ASCII
525
        self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
526
                         my_config._get_user_id())
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
527
528
    def test_absent_user_id(self):
529
        config_file = StringIO("")
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
530
        my_config = config.GlobalConfig()
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
531
        my_config._parser = my_config._get_parser(file=config_file)
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
532
        self.assertEqual(None, my_config._get_user_id())
533
534
    def test_configured_editor(self):
1551.2.20 by Aaron Bentley
Treated config files as utf-8
535
        config_file = StringIO(sample_config_text.encode('utf-8'))
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
536
        my_config = config.GlobalConfig()
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
537
        my_config._parser = my_config._get_parser(file=config_file)
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
538
        self.assertEqual("vim", my_config.get_editor())
539
1442.1.17 by Robert Collins
allow global overriding of signature policy to force checking, or (pointless but allowed) to set auto checking
540
    def test_signatures_always(self):
541
        config_file = StringIO(sample_always_signatures)
542
        my_config = config.GlobalConfig()
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
543
        my_config._parser = my_config._get_parser(file=config_file)
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
544
        self.assertEqual(config.CHECK_NEVER,
1442.1.17 by Robert Collins
allow global overriding of signature policy to force checking, or (pointless but allowed) to set auto checking
545
                         my_config.signature_checking())
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
546
        self.assertEqual(config.SIGN_ALWAYS,
547
                         my_config.signing_policy())
1442.1.21 by Robert Collins
create signature_needed() call for commit to trigger creating signatures
548
        self.assertEqual(True, my_config.signature_needed())
1442.1.17 by Robert Collins
allow global overriding of signature policy to force checking, or (pointless but allowed) to set auto checking
549
550
    def test_signatures_if_possible(self):
551
        config_file = StringIO(sample_maybe_signatures)
552
        my_config = config.GlobalConfig()
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
553
        my_config._parser = my_config._get_parser(file=config_file)
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
554
        self.assertEqual(config.CHECK_NEVER,
1442.1.17 by Robert Collins
allow global overriding of signature policy to force checking, or (pointless but allowed) to set auto checking
555
                         my_config.signature_checking())
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
556
        self.assertEqual(config.SIGN_WHEN_REQUIRED,
557
                         my_config.signing_policy())
1442.1.21 by Robert Collins
create signature_needed() call for commit to trigger creating signatures
558
        self.assertEqual(False, my_config.signature_needed())
1442.1.17 by Robert Collins
allow global overriding of signature policy to force checking, or (pointless but allowed) to set auto checking
559
1442.1.16 by Robert Collins
allow global overriding of signature policy to never check
560
    def test_signatures_ignore(self):
561
        config_file = StringIO(sample_ignore_signatures)
562
        my_config = config.GlobalConfig()
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
563
        my_config._parser = my_config._get_parser(file=config_file)
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
564
        self.assertEqual(config.CHECK_ALWAYS,
1442.1.16 by Robert Collins
allow global overriding of signature policy to never check
565
                         my_config.signature_checking())
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
566
        self.assertEqual(config.SIGN_NEVER,
567
                         my_config.signing_policy())
1442.1.21 by Robert Collins
create signature_needed() call for commit to trigger creating signatures
568
        self.assertEqual(False, my_config.signature_needed())
1442.1.16 by Robert Collins
allow global overriding of signature policy to never check
569
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
570
    def _get_sample_config(self):
1551.2.20 by Aaron Bentley
Treated config files as utf-8
571
        config_file = StringIO(sample_config_text.encode('utf-8'))
1534.7.154 by Aaron Bentley
Removed changes from bzr.ab 1529..1536
572
        my_config = config.GlobalConfig()
573
        my_config._parser = my_config._get_parser(file=config_file)
574
        return my_config
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
575
1442.1.56 by Robert Collins
gpg_signing_command configuration item
576
    def test_gpg_signing_command(self):
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
577
        my_config = self._get_sample_config()
1442.1.56 by Robert Collins
gpg_signing_command configuration item
578
        self.assertEqual("gnome-gpg", my_config.gpg_signing_command())
579
        self.assertEqual(False, my_config.signature_needed())
580
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
581
    def _get_empty_config(self):
582
        config_file = StringIO("")
583
        my_config = config.GlobalConfig()
584
        my_config._parser = my_config._get_parser(file=config_file)
585
        return my_config
586
1442.1.59 by Robert Collins
Add re-sign command to generate a digital signature on a single revision.
587
    def test_gpg_signing_command_unset(self):
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
588
        my_config = self._get_empty_config()
1442.1.59 by Robert Collins
Add re-sign command to generate a digital signature on a single revision.
589
        self.assertEqual("gpg", my_config.gpg_signing_command())
590
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
591
    def test_get_user_option_default(self):
592
        my_config = self._get_empty_config()
593
        self.assertEqual(None, my_config.get_user_option('no_option'))
594
595
    def test_get_user_option_global(self):
596
        my_config = self._get_sample_config()
597
        self.assertEqual("something",
598
                         my_config.get_user_option('user_global_option'))
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
599
1472 by Robert Collins
post commit hook, first pass implementation
600
    def test_post_commit_default(self):
601
        my_config = self._get_sample_config()
602
        self.assertEqual(None, my_config.post_commit())
603
1553.2.9 by Erik Bågfors
log_formatter => log_format for "named" formatters
604
    def test_configured_logformat(self):
1553.2.8 by Erik Bågfors
tests for config log_formatter
605
        my_config = self._get_sample_config()
1553.2.9 by Erik Bågfors
log_formatter => log_format for "named" formatters
606
        self.assertEqual("short", my_config.log_format())
1553.2.8 by Erik Bågfors
tests for config log_formatter
607
1553.6.12 by Erik Bågfors
remove AliasConfig, based on input from abentley
608
    def test_get_alias(self):
609
        my_config = self._get_sample_config()
610
        self.assertEqual('help', my_config.get_alias('h'))
611
2900.3.6 by Tim Penhey
Added tests.
612
    def test_get_aliases(self):
613
        my_config = self._get_sample_config()
614
        aliases = my_config.get_aliases()
615
        self.assertEqual(2, len(aliases))
616
        sorted_keys = sorted(aliases)
617
        self.assertEqual('help', aliases[sorted_keys[0]])
618
        self.assertEqual(sample_long_alias, aliases[sorted_keys[1]])
619
1553.6.12 by Erik Bågfors
remove AliasConfig, based on input from abentley
620
    def test_get_no_alias(self):
621
        my_config = self._get_sample_config()
622
        self.assertEqual(None, my_config.get_alias('foo'))
623
624
    def test_get_long_alias(self):
625
        my_config = self._get_sample_config()
626
        self.assertEqual(sample_long_alias, my_config.get_alias('ll'))
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
627
1704.2.18 by Martin Pool
Remove duplicated TestLocationConfig and update previously hidden tests. (#32587)
628
2900.3.6 by Tim Penhey
Added tests.
629
class TestGlobalConfigSavingOptions(tests.TestCaseInTempDir):
630
631
    def test_empty(self):
632
        my_config = config.GlobalConfig()
633
        self.assertEqual(0, len(my_config.get_aliases()))
634
635
    def test_set_alias(self):
636
        my_config = config.GlobalConfig()
637
        alias_value = 'commit --strict'
638
        my_config.set_alias('commit', alias_value)
639
        new_config = config.GlobalConfig()
640
        self.assertEqual(alias_value, new_config.get_alias('commit'))
641
642
    def test_remove_alias(self):
643
        my_config = config.GlobalConfig()
644
        my_config.set_alias('commit', 'commit --strict')
645
        # Now remove the alias again.
646
        my_config.unset_alias('commit')
647
        new_config = config.GlobalConfig()
648
        self.assertIs(None, new_config.get_alias('commit'))
649
650
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
651
class TestLocationConfig(tests.TestCaseInTempDir):
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
652
653
    def test_constructs(self):
654
        my_config = config.LocationConfig('http://example.com')
655
        self.assertRaises(TypeError, config.LocationConfig)
656
657
    def test_branch_calls_read_filenames(self):
1474 by Robert Collins
Merge from Aaron Bentley.
658
        # This is testing the correct file names are provided.
659
        # TODO: consolidate with the test for GlobalConfigs filename checks.
660
        #
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
661
        # replace the class that is constructed, to check its parameters
1474 by Robert Collins
Merge from Aaron Bentley.
662
        oldparserclass = config.ConfigObj
663
        config.ConfigObj = InstrumentedConfigObj
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
664
        try:
1770.2.2 by Aaron Bentley
Rename branches.conf to locations.conf
665
            my_config = config.LocationConfig('http://www.example.com')
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
666
            parser = my_config._get_parser()
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
667
        finally:
1474 by Robert Collins
Merge from Aaron Bentley.
668
            config.ConfigObj = oldparserclass
669
        self.failUnless(isinstance(parser, InstrumentedConfigObj))
670
        self.assertEqual(parser._calls,
1770.2.2 by Aaron Bentley
Rename branches.conf to locations.conf
671
                         [('__init__', config.locations_config_filename(),
1704.2.18 by Martin Pool
Remove duplicated TestLocationConfig and update previously hidden tests. (#32587)
672
                           'utf-8')])
1711.4.29 by John Arbash Meinel
Alexander Belchenko, fix test_config to use ensure_config_dir, rather than os.mkdir()
673
        config.ensure_config_dir_exists()
674
        #os.mkdir(config.config_dir())
1770.2.2 by Aaron Bentley
Rename branches.conf to locations.conf
675
        f = file(config.branches_config_filename(), 'wb')
676
        f.write('')
677
        f.close()
678
        oldparserclass = config.ConfigObj
679
        config.ConfigObj = InstrumentedConfigObj
680
        try:
681
            my_config = config.LocationConfig('http://www.example.com')
682
            parser = my_config._get_parser()
683
        finally:
684
            config.ConfigObj = oldparserclass
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
685
686
    def test_get_global_config(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
687
        my_config = config.BranchConfig(FakeBranch('http://example.com'))
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
688
        global_config = my_config._get_global_config()
689
        self.failUnless(isinstance(global_config, config.GlobalConfig))
690
        self.failUnless(global_config is my_config._get_global_config())
691
1993.3.1 by James Henstridge
first go at making location config lookup recursive
692
    def test__get_matching_sections_no_match(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
693
        self.get_branch_config('/')
1993.3.1 by James Henstridge
first go at making location config lookup recursive
694
        self.assertEqual([], self.my_location_config._get_matching_sections())
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
695
1993.3.1 by James Henstridge
first go at making location config lookup recursive
696
    def test__get_matching_sections_exact(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
697
        self.get_branch_config('http://www.example.com')
1993.3.3 by James Henstridge
make _get_matching_sections() return (section, extra_path) tuples, and adjust other code to match
698
        self.assertEqual([('http://www.example.com', '')],
1993.3.1 by James Henstridge
first go at making location config lookup recursive
699
                         self.my_location_config._get_matching_sections())
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
700
1993.3.1 by James Henstridge
first go at making location config lookup recursive
701
    def test__get_matching_sections_suffix_does_not(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
702
        self.get_branch_config('http://www.example.com-com')
1993.3.1 by James Henstridge
first go at making location config lookup recursive
703
        self.assertEqual([], self.my_location_config._get_matching_sections())
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
704
1993.3.1 by James Henstridge
first go at making location config lookup recursive
705
    def test__get_matching_sections_subdir_recursive(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
706
        self.get_branch_config('http://www.example.com/com')
1993.3.3 by James Henstridge
make _get_matching_sections() return (section, extra_path) tuples, and adjust other code to match
707
        self.assertEqual([('http://www.example.com', 'com')],
1993.3.1 by James Henstridge
first go at making location config lookup recursive
708
                         self.my_location_config._get_matching_sections())
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
709
1993.3.5 by James Henstridge
add back recurse=False option to config file
710
    def test__get_matching_sections_ignoreparent(self):
1993.3.3 by James Henstridge
make _get_matching_sections() return (section, extra_path) tuples, and adjust other code to match
711
        self.get_branch_config('http://www.example.com/ignoreparent')
712
        self.assertEqual([('http://www.example.com/ignoreparent', '')],
1993.3.1 by James Henstridge
first go at making location config lookup recursive
713
                         self.my_location_config._get_matching_sections())
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
714
1993.3.5 by James Henstridge
add back recurse=False option to config file
715
    def test__get_matching_sections_ignoreparent_subdir(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
716
        self.get_branch_config(
1993.3.3 by James Henstridge
make _get_matching_sections() return (section, extra_path) tuples, and adjust other code to match
717
            'http://www.example.com/ignoreparent/childbranch')
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
718
        self.assertEqual([('http://www.example.com/ignoreparent',
719
                           'childbranch')],
1993.3.1 by James Henstridge
first go at making location config lookup recursive
720
                         self.my_location_config._get_matching_sections())
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
721
1993.3.1 by James Henstridge
first go at making location config lookup recursive
722
    def test__get_matching_sections_subdir_trailing_slash(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
723
        self.get_branch_config('/b')
1993.3.3 by James Henstridge
make _get_matching_sections() return (section, extra_path) tuples, and adjust other code to match
724
        self.assertEqual([('/b/', '')],
1993.3.1 by James Henstridge
first go at making location config lookup recursive
725
                         self.my_location_config._get_matching_sections())
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
726
1993.3.1 by James Henstridge
first go at making location config lookup recursive
727
    def test__get_matching_sections_subdir_child(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
728
        self.get_branch_config('/a/foo')
1993.3.3 by James Henstridge
make _get_matching_sections() return (section, extra_path) tuples, and adjust other code to match
729
        self.assertEqual([('/a/*', ''), ('/a/', 'foo')],
1993.3.1 by James Henstridge
first go at making location config lookup recursive
730
                         self.my_location_config._get_matching_sections())
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
731
1993.3.1 by James Henstridge
first go at making location config lookup recursive
732
    def test__get_matching_sections_subdir_child_child(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
733
        self.get_branch_config('/a/foo/bar')
1993.3.3 by James Henstridge
make _get_matching_sections() return (section, extra_path) tuples, and adjust other code to match
734
        self.assertEqual([('/a/*', 'bar'), ('/a/', 'foo/bar')],
1993.3.1 by James Henstridge
first go at making location config lookup recursive
735
                         self.my_location_config._get_matching_sections())
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
736
1993.3.1 by James Henstridge
first go at making location config lookup recursive
737
    def test__get_matching_sections_trailing_slash_with_children(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
738
        self.get_branch_config('/a/')
1993.3.3 by James Henstridge
make _get_matching_sections() return (section, extra_path) tuples, and adjust other code to match
739
        self.assertEqual([('/a/', '')],
1993.3.1 by James Henstridge
first go at making location config lookup recursive
740
                         self.my_location_config._get_matching_sections())
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
741
1993.3.1 by James Henstridge
first go at making location config lookup recursive
742
    def test__get_matching_sections_explicit_over_glob(self):
743
        # XXX: 2006-09-08 jamesh
744
        # This test only passes because ord('c') > ord('*').  If there
745
        # was a config section for '/a/?', it would get precedence
746
        # over '/a/c'.
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
747
        self.get_branch_config('/a/c')
1993.3.3 by James Henstridge
make _get_matching_sections() return (section, extra_path) tuples, and adjust other code to match
748
        self.assertEqual([('/a/c', ''), ('/a/*', ''), ('/a/', 'c')],
1993.3.1 by James Henstridge
first go at making location config lookup recursive
749
                         self.my_location_config._get_matching_sections())
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
750
2120.6.3 by James Henstridge
add some more tests for getting policy options, and behaviour of get_user_option in the presence of config policies
751
    def test__get_option_policy_normal(self):
752
        self.get_branch_config('http://www.example.com')
753
        self.assertEqual(
754
            self.my_location_config._get_config_policy(
755
            'http://www.example.com', 'normal_option'),
756
            config.POLICY_NONE)
757
758
    def test__get_option_policy_norecurse(self):
759
        self.get_branch_config('http://www.example.com')
760
        self.assertEqual(
761
            self.my_location_config._get_option_policy(
762
            'http://www.example.com', 'norecurse_option'),
763
            config.POLICY_NORECURSE)
764
        # Test old recurse=False setting:
765
        self.assertEqual(
766
            self.my_location_config._get_option_policy(
767
            'http://www.example.com/norecurse', 'normal_option'),
768
            config.POLICY_NORECURSE)
769
770
    def test__get_option_policy_normal(self):
771
        self.get_branch_config('http://www.example.com')
772
        self.assertEqual(
773
            self.my_location_config._get_option_policy(
774
            'http://www.example.com', 'appendpath_option'),
775
            config.POLICY_APPENDPATH)
776
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
777
    def test_location_without_username(self):
1993.3.3 by James Henstridge
make _get_matching_sections() return (section, extra_path) tuples, and adjust other code to match
778
        self.get_branch_config('http://www.example.com/ignoreparent')
1704.2.18 by Martin Pool
Remove duplicated TestLocationConfig and update previously hidden tests. (#32587)
779
        self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
780
                         self.my_config.username())
781
782
    def test_location_not_listed(self):
1704.2.18 by Martin Pool
Remove duplicated TestLocationConfig and update previously hidden tests. (#32587)
783
        """Test that the global username is used when no location matches"""
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
784
        self.get_branch_config('/home/robertc/sources')
1704.2.18 by Martin Pool
Remove duplicated TestLocationConfig and update previously hidden tests. (#32587)
785
        self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
786
                         self.my_config.username())
787
1442.1.13 by Robert Collins
branches.conf is now able to override the users email
788
    def test_overriding_location(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
789
        self.get_branch_config('http://www.example.com/foo')
1442.1.13 by Robert Collins
branches.conf is now able to override the users email
790
        self.assertEqual('Robert Collins <robertc@example.org>',
791
                         self.my_config.username())
1442.1.16 by Robert Collins
allow global overriding of signature policy to never check
792
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
793
    def test_signatures_not_set(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
794
        self.get_branch_config('http://www.example.com',
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
795
                                 global_config=sample_ignore_signatures)
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
796
        self.assertEqual(config.CHECK_ALWAYS,
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
797
                         self.my_config.signature_checking())
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
798
        self.assertEqual(config.SIGN_NEVER,
799
                         self.my_config.signing_policy())
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
800
801
    def test_signatures_never(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
802
        self.get_branch_config('/a/c')
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
803
        self.assertEqual(config.CHECK_NEVER,
804
                         self.my_config.signature_checking())
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
805
1442.1.16 by Robert Collins
allow global overriding of signature policy to never check
806
    def test_signatures_when_available(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
807
        self.get_branch_config('/a/', global_config=sample_ignore_signatures)
1442.1.16 by Robert Collins
allow global overriding of signature policy to never check
808
        self.assertEqual(config.CHECK_IF_POSSIBLE,
809
                         self.my_config.signature_checking())
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
810
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
811
    def test_signatures_always(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
812
        self.get_branch_config('/b')
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
813
        self.assertEqual(config.CHECK_ALWAYS,
814
                         self.my_config.signature_checking())
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
815
1442.1.56 by Robert Collins
gpg_signing_command configuration item
816
    def test_gpg_signing_command(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
817
        self.get_branch_config('/b')
1442.1.56 by Robert Collins
gpg_signing_command configuration item
818
        self.assertEqual("gnome-gpg", self.my_config.gpg_signing_command())
819
820
    def test_gpg_signing_command_missing(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
821
        self.get_branch_config('/a')
1442.1.56 by Robert Collins
gpg_signing_command configuration item
822
        self.assertEqual("false", self.my_config.gpg_signing_command())
823
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
824
    def test_get_user_option_global(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
825
        self.get_branch_config('/a')
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
826
        self.assertEqual('something',
827
                         self.my_config.get_user_option('user_global_option'))
828
829
    def test_get_user_option_local(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
830
        self.get_branch_config('/a')
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
831
        self.assertEqual('local',
832
                         self.my_config.get_user_option('user_local_option'))
1993.3.3 by James Henstridge
make _get_matching_sections() return (section, extra_path) tuples, and adjust other code to match
833
2120.6.3 by James Henstridge
add some more tests for getting policy options, and behaviour of get_user_option in the presence of config policies
834
    def test_get_user_option_appendpath(self):
835
        # returned as is for the base path:
836
        self.get_branch_config('http://www.example.com')
837
        self.assertEqual('append',
838
                         self.my_config.get_user_option('appendpath_option'))
839
        # Extra path components get appended:
840
        self.get_branch_config('http://www.example.com/a/b/c')
841
        self.assertEqual('append/a/b/c',
842
                         self.my_config.get_user_option('appendpath_option'))
843
        # Overriden for http://www.example.com/dir, where it is a
844
        # normal option:
845
        self.get_branch_config('http://www.example.com/dir/a/b/c')
846
        self.assertEqual('normal',
847
                         self.my_config.get_user_option('appendpath_option'))
848
849
    def test_get_user_option_norecurse(self):
850
        self.get_branch_config('http://www.example.com')
851
        self.assertEqual('norecurse',
852
                         self.my_config.get_user_option('norecurse_option'))
853
        self.get_branch_config('http://www.example.com/dir')
854
        self.assertEqual(None,
855
                         self.my_config.get_user_option('norecurse_option'))
856
        # http://www.example.com/norecurse is a recurse=False section
857
        # that redefines normal_option.  Subdirectories do not pick up
858
        # this redefinition.
859
        self.get_branch_config('http://www.example.com/norecurse')
860
        self.assertEqual('norecurse',
861
                         self.my_config.get_user_option('normal_option'))
862
        self.get_branch_config('http://www.example.com/norecurse/subdir')
863
        self.assertEqual('normal',
864
                         self.my_config.get_user_option('normal_option'))
865
2120.6.4 by James Henstridge
add support for specifying policy when storing options
866
    def test_set_user_option_norecurse(self):
867
        self.get_branch_config('http://www.example.com')
868
        self.my_config.set_user_option('foo', 'bar',
869
                                       store=config.STORE_LOCATION_NORECURSE)
870
        self.assertEqual(
871
            self.my_location_config._get_option_policy(
872
            'http://www.example.com', 'foo'),
873
            config.POLICY_NORECURSE)
874
875
    def test_set_user_option_appendpath(self):
876
        self.get_branch_config('http://www.example.com')
877
        self.my_config.set_user_option('foo', 'bar',
878
                                       store=config.STORE_LOCATION_APPENDPATH)
879
        self.assertEqual(
880
            self.my_location_config._get_option_policy(
881
            'http://www.example.com', 'foo'),
882
            config.POLICY_APPENDPATH)
883
884
    def test_set_user_option_change_policy(self):
885
        self.get_branch_config('http://www.example.com')
886
        self.my_config.set_user_option('norecurse_option', 'normal',
887
                                       store=config.STORE_LOCATION)
888
        self.assertEqual(
889
            self.my_location_config._get_option_policy(
890
            'http://www.example.com', 'norecurse_option'),
891
            config.POLICY_NONE)
892
893
    def test_set_user_option_recurse_false_section(self):
2120.6.9 by James Henstridge
Fixes for issues brought up in John's review
894
        # The following section has recurse=False set.  The test is to
895
        # make sure that a normal option can be added to the section,
896
        # converting recurse=False to the norecurse policy.
2120.6.4 by James Henstridge
add support for specifying policy when storing options
897
        self.get_branch_config('http://www.example.com/norecurse')
2120.6.11 by James Henstridge
s/0.13/0.14/ in deprecation warning
898
        self.callDeprecated(['The recurse option is deprecated as of 0.14.  '
2120.6.9 by James Henstridge
Fixes for issues brought up in John's review
899
                             'The section "http://www.example.com/norecurse" '
900
                             'has been converted to use policies.'],
901
                            self.my_config.set_user_option,
902
                            'foo', 'bar', store=config.STORE_LOCATION)
2120.6.4 by James Henstridge
add support for specifying policy when storing options
903
        self.assertEqual(
904
            self.my_location_config._get_option_policy(
905
            'http://www.example.com/norecurse', 'foo'),
906
            config.POLICY_NONE)
907
        # The previously existing option is still norecurse:
908
        self.assertEqual(
909
            self.my_location_config._get_option_policy(
910
            'http://www.example.com/norecurse', 'normal_option'),
911
            config.POLICY_NORECURSE)
912
1472 by Robert Collins
post commit hook, first pass implementation
913
    def test_post_commit_default(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
914
        self.get_branch_config('/a/c')
1185.31.25 by John Arbash Meinel
Renamed all of the tests from selftest/foo.py to tests/test_foo.py
915
        self.assertEqual('bzrlib.tests.test_config.post_commit',
1472 by Robert Collins
post commit hook, first pass implementation
916
                         self.my_config.post_commit())
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
917
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
918
    def get_branch_config(self, location, global_config=None):
1502 by Robert Collins
Bugfix the config test suite to not create .bazaar in the dir where it is run.
919
        if global_config is None:
1551.2.20 by Aaron Bentley
Treated config files as utf-8
920
            global_file = StringIO(sample_config_text.encode('utf-8'))
1502 by Robert Collins
Bugfix the config test suite to not create .bazaar in the dir where it is run.
921
        else:
1551.2.20 by Aaron Bentley
Treated config files as utf-8
922
            global_file = StringIO(global_config.encode('utf-8'))
923
        branches_file = StringIO(sample_branches_text.encode('utf-8'))
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
924
        self.my_config = config.BranchConfig(FakeBranch(location))
925
        # Force location config to use specified file
926
        self.my_location_config = self.my_config._get_location_config()
927
        self.my_location_config._get_parser(branches_file)
928
        # Force global config to use specified file
1502 by Robert Collins
Bugfix the config test suite to not create .bazaar in the dir where it is run.
929
        self.my_config._get_global_config()._get_parser(global_file)
930
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
931
    def test_set_user_setting_sets_and_saves(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
932
        self.get_branch_config('/a/c')
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
933
        record = InstrumentedConfigObj("foo")
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
934
        self.my_location_config._parser = record
1185.62.6 by John Arbash Meinel
Updated test_set_user_setting_sets_and_saves to remove the print statement, and make sure it is doing the right thing
935
936
        real_mkdir = os.mkdir
937
        self.created = False
938
        def checked_mkdir(path, mode=0777):
939
            self.log('making directory: %s', path)
940
            real_mkdir(path, mode)
941
            self.created = True
942
943
        os.mkdir = checked_mkdir
944
        try:
2120.6.10 by James Henstridge
Catch another deprecation warning, and more cleanup
945
            self.callDeprecated(['The recurse option is deprecated as of '
2120.6.11 by James Henstridge
s/0.13/0.14/ in deprecation warning
946
                                 '0.14.  The section "/a/c" has been '
2120.6.10 by James Henstridge
Catch another deprecation warning, and more cleanup
947
                                 'converted to use policies.'],
948
                                self.my_config.set_user_option,
949
                                'foo', 'bar', store=config.STORE_LOCATION)
1185.62.6 by John Arbash Meinel
Updated test_set_user_setting_sets_and_saves to remove the print statement, and make sure it is doing the right thing
950
        finally:
951
            os.mkdir = real_mkdir
952
953
        self.failUnless(self.created, 'Failed to create ~/.bazaar')
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
954
        self.assertEqual([('__contains__', '/a/c'),
955
                          ('__contains__', '/a/c/'),
956
                          ('__setitem__', '/a/c', {}),
957
                          ('__getitem__', '/a/c'),
958
                          ('__setitem__', 'foo', 'bar'),
2120.6.4 by James Henstridge
add support for specifying policy when storing options
959
                          ('__getitem__', '/a/c'),
960
                          ('as_bool', 'recurse'),
961
                          ('__getitem__', '/a/c'),
962
                          ('__delitem__', 'recurse'),
963
                          ('__getitem__', '/a/c'),
964
                          ('keys',),
2120.6.8 by James Henstridge
Change syntax for setting config option policies. Rather than
965
                          ('__getitem__', '/a/c'),
966
                          ('__contains__', 'foo:policy'),
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
967
                          ('write',)],
968
                         record._calls[1:])
969
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
970
    def test_set_user_setting_sets_and_saves2(self):
971
        self.get_branch_config('/a/c')
972
        self.assertIs(self.my_config.get_user_option('foo'), None)
973
        self.my_config.set_user_option('foo', 'bar')
974
        self.assertEqual(
3616.2.6 by Mark Hammond
Fix test_set_user_setting_sets_and_saves2 on windows by stripping EOL
975
            self.my_config.branch.control_files.files['branch.conf'].strip(),
976
            'foo = bar')
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
977
        self.assertEqual(self.my_config.get_user_option('foo'), 'bar')
2120.6.4 by James Henstridge
add support for specifying policy when storing options
978
        self.my_config.set_user_option('foo', 'baz',
979
                                       store=config.STORE_LOCATION)
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
980
        self.assertEqual(self.my_config.get_user_option('foo'), 'baz')
981
        self.my_config.set_user_option('foo', 'qux')
982
        self.assertEqual(self.my_config.get_user_option('foo'), 'baz')
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
983
1551.18.17 by Aaron Bentley
Introduce bzr_remote_path configuration variable
984
    def test_get_bzr_remote_path(self):
985
        my_config = config.LocationConfig('/a/c')
986
        self.assertEqual('bzr', my_config.get_bzr_remote_path())
987
        my_config.set_user_option('bzr_remote_path', '/path-bzr')
988
        self.assertEqual('/path-bzr', my_config.get_bzr_remote_path())
989
        os.environ['BZR_REMOTE_PATH'] = '/environ-bzr'
990
        self.assertEqual('/environ-bzr', my_config.get_bzr_remote_path())
991
1185.62.7 by John Arbash Meinel
Whitespace cleanup.
992
1770.2.8 by Aaron Bentley
Add precedence test
993
precedence_global = 'option = global'
994
precedence_branch = 'option = branch'
995
precedence_location = """
996
[http://]
997
recurse = true
998
option = recurse
999
[http://example.com/specific]
1000
option = exact
1001
"""
1002
1003
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
1004
class TestBranchConfigItems(tests.TestCaseInTempDir):
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
1005
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
1006
    def get_branch_config(self, global_config=None, location=None,
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
1007
                          location_config=None, branch_data_config=None):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
1008
        my_config = config.BranchConfig(FakeBranch(location))
1009
        if global_config is not None:
1010
            global_file = StringIO(global_config.encode('utf-8'))
1011
            my_config._get_global_config()._get_parser(global_file)
1012
        self.my_location_config = my_config._get_location_config()
1013
        if location_config is not None:
1014
            location_file = StringIO(location_config.encode('utf-8'))
1015
            self.my_location_config._get_parser(location_file)
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
1016
        if branch_data_config is not None:
1017
            my_config.branch.control_files.files['branch.conf'] = \
1018
                branch_data_config
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
1019
        return my_config
1020
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
1021
    def test_user_id(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
1022
        branch = FakeBranch(user_id='Robert Collins <robertc@example.net>')
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
1023
        my_config = config.BranchConfig(branch)
1024
        self.assertEqual("Robert Collins <robertc@example.net>",
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
1025
                         my_config.username())
3388.2.3 by Martin Pool
Fix up more uses of LockableFiles.get_utf8 in tests
1026
        my_config.branch.control_files.files['email'] = "John"
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
1027
        my_config.set_user_option('email',
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
1028
                                  "Robert Collins <robertc@example.org>")
1029
        self.assertEqual("John", my_config.username())
3388.2.3 by Martin Pool
Fix up more uses of LockableFiles.get_utf8 in tests
1030
        del my_config.branch.control_files.files['email']
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
1031
        self.assertEqual("Robert Collins <robertc@example.org>",
1032
                         my_config.username())
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
1033
1034
    def test_not_set_in_branch(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
1035
        my_config = self.get_branch_config(sample_config_text)
1551.2.21 by Aaron Bentley
Formatted unicode config tests as ASCII
1036
        self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
1037
                         my_config._get_user_id())
3388.2.3 by Martin Pool
Fix up more uses of LockableFiles.get_utf8 in tests
1038
        my_config.branch.control_files.files['email'] = "John"
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
1039
        self.assertEqual("John", my_config._get_user_id())
1040
1861.4.1 by Matthieu Moy
BZREMAIL renamed to BZR_EMAIL.
1041
    def test_BZR_EMAIL_OVERRIDES(self):
1042
        os.environ['BZR_EMAIL'] = "Robert Collins <robertc@example.org>"
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
1043
        branch = FakeBranch()
1044
        my_config = config.BranchConfig(branch)
1045
        self.assertEqual("Robert Collins <robertc@example.org>",
1046
                         my_config.username())
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
1047
1442.1.19 by Robert Collins
BranchConfigs inherit signature_checking policy from their LocationConfig.
1048
    def test_signatures_forced(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
1049
        my_config = self.get_branch_config(
1050
            global_config=sample_always_signatures)
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
1051
        self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
1052
        self.assertEqual(config.SIGN_ALWAYS, my_config.signing_policy())
1053
        self.assertTrue(my_config.signature_needed())
1442.1.56 by Robert Collins
gpg_signing_command configuration item
1054
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
1055
    def test_signatures_forced_branch(self):
1056
        my_config = self.get_branch_config(
1057
            global_config=sample_ignore_signatures,
1058
            branch_data_config=sample_always_signatures)
1059
        self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
1060
        self.assertEqual(config.SIGN_ALWAYS, my_config.signing_policy())
1061
        self.assertTrue(my_config.signature_needed())
1062
1442.1.56 by Robert Collins
gpg_signing_command configuration item
1063
    def test_gpg_signing_command(self):
1770.2.10 by Aaron Bentley
Added test that branch_config can't influence gpg_signing_command
1064
        my_config = self.get_branch_config(
1065
            # branch data cannot set gpg_signing_command
1066
            branch_data_config="gpg_signing_command=pgp")
1551.2.20 by Aaron Bentley
Treated config files as utf-8
1067
        config_file = StringIO(sample_config_text.encode('utf-8'))
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
1068
        my_config._get_global_config()._get_parser(config_file)
1442.1.56 by Robert Collins
gpg_signing_command configuration item
1069
        self.assertEqual('gnome-gpg', my_config.gpg_signing_command())
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
1070
1071
    def test_get_user_option_global(self):
1072
        branch = FakeBranch()
1073
        my_config = config.BranchConfig(branch)
1551.2.20 by Aaron Bentley
Treated config files as utf-8
1074
        config_file = StringIO(sample_config_text.encode('utf-8'))
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
1075
        (my_config._get_global_config()._get_parser(config_file))
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
1076
        self.assertEqual('something',
1077
                         my_config.get_user_option('user_global_option'))
1472 by Robert Collins
post commit hook, first pass implementation
1078
1079
    def test_post_commit_default(self):
1080
        branch = FakeBranch()
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
1081
        my_config = self.get_branch_config(sample_config_text, '/a/c',
1082
                                           sample_branches_text)
1083
        self.assertEqual(my_config.branch.base, '/a/c')
1185.31.25 by John Arbash Meinel
Renamed all of the tests from selftest/foo.py to tests/test_foo.py
1084
        self.assertEqual('bzrlib.tests.test_config.post_commit',
1472 by Robert Collins
post commit hook, first pass implementation
1085
                         my_config.post_commit())
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
1086
        my_config.set_user_option('post_commit', 'rmtree_root')
1087
        # post-commit is ignored when bresent in branch data
1088
        self.assertEqual('bzrlib.tests.test_config.post_commit',
1089
                         my_config.post_commit())
2120.6.4 by James Henstridge
add support for specifying policy when storing options
1090
        my_config.set_user_option('post_commit', 'rmtree_root',
1091
                                  store=config.STORE_LOCATION)
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
1092
        self.assertEqual('rmtree_root', my_config.post_commit())
1185.33.31 by Martin Pool
Make annotate cope better with revisions committed without a valid
1093
1770.2.8 by Aaron Bentley
Add precedence test
1094
    def test_config_precedence(self):
1095
        my_config = self.get_branch_config(global_config=precedence_global)
1096
        self.assertEqual(my_config.get_user_option('option'), 'global')
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
1097
        my_config = self.get_branch_config(global_config=precedence_global,
1770.2.8 by Aaron Bentley
Add precedence test
1098
                                      branch_data_config=precedence_branch)
1099
        self.assertEqual(my_config.get_user_option('option'), 'branch')
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
1100
        my_config = self.get_branch_config(global_config=precedence_global,
1770.2.8 by Aaron Bentley
Add precedence test
1101
                                      branch_data_config=precedence_branch,
1102
                                      location_config=precedence_location)
1103
        self.assertEqual(my_config.get_user_option('option'), 'recurse')
2991.2.2 by Vincent Ladeuil
No tests worth adding after upgrading to configobj-4.4.0.
1104
        my_config = self.get_branch_config(global_config=precedence_global,
1770.2.8 by Aaron Bentley
Add precedence test
1105
                                      branch_data_config=precedence_branch,
1106
                                      location_config=precedence_location,
1107
                                      location='http://example.com/specific')
1108
        self.assertEqual(my_config.get_user_option('option'), 'exact')
1109
2681.1.8 by Aaron Bentley
Add Thunderbird support to bzr send
1110
    def test_get_mail_client(self):
1111
        config = self.get_branch_config()
1112
        client = config.get_mail_client()
2681.1.24 by Aaron Bentley
Handle default mail client by trying xdg-email, falling back to editor
1113
        self.assertIsInstance(client, mail_client.DefaultMail)
1114
2790.2.2 by Keir Mierle
Change alphabetic ordering into two categories; one for specific clients the other for generic options.
1115
        # Specific clients
2681.1.21 by Aaron Bentley
Refactor prompt generation to make it testable, test it with unicode
1116
        config.set_user_option('mail_client', 'evolution')
1117
        client = config.get_mail_client()
1118
        self.assertIsInstance(client, mail_client.Evolution)
1119
2681.5.1 by ghigo
Add KMail support to bzr send
1120
        config.set_user_option('mail_client', 'kmail')
1121
        client = config.get_mail_client()
1122
        self.assertIsInstance(client, mail_client.KMail)
1123
2790.2.1 by Keir Mierle
Add Mutt as a supported client email program. Also rearranges various listings
1124
        config.set_user_option('mail_client', 'mutt')
1125
        client = config.get_mail_client()
1126
        self.assertIsInstance(client, mail_client.Mutt)
1127
1128
        config.set_user_option('mail_client', 'thunderbird')
1129
        client = config.get_mail_client()
1130
        self.assertIsInstance(client, mail_client.Thunderbird)
1131
2790.2.2 by Keir Mierle
Change alphabetic ordering into two categories; one for specific clients the other for generic options.
1132
        # Generic options
1133
        config.set_user_option('mail_client', 'default')
1134
        client = config.get_mail_client()
1135
        self.assertIsInstance(client, mail_client.DefaultMail)
1136
1137
        config.set_user_option('mail_client', 'editor')
1138
        client = config.get_mail_client()
1139
        self.assertIsInstance(client, mail_client.Editor)
1140
1141
        config.set_user_option('mail_client', 'mapi')
1142
        client = config.get_mail_client()
1143
        self.assertIsInstance(client, mail_client.MAPIClient)
1144
2681.1.23 by Aaron Bentley
Add support for xdg-email
1145
        config.set_user_option('mail_client', 'xdg-email')
1146
        client = config.get_mail_client()
1147
        self.assertIsInstance(client, mail_client.XDGEmail)
1148
2681.1.10 by Aaron Bentley
Clean up handling of unknown mail clients
1149
        config.set_user_option('mail_client', 'firebird')
1150
        self.assertRaises(errors.UnknownMailClient, config.get_mail_client)
1151
1185.33.31 by Martin Pool
Make annotate cope better with revisions committed without a valid
1152
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
1153
class TestMailAddressExtraction(tests.TestCase):
1185.33.31 by Martin Pool
Make annotate cope better with revisions committed without a valid
1154
1155
    def test_extract_email_address(self):
1156
        self.assertEqual('jane@test.com',
1157
                         config.extract_email_address('Jane <jane@test.com>'))
2055.2.2 by John Arbash Meinel
Switch extract_email_address() to use a more specific exception
1158
        self.assertRaises(errors.NoEmailInUsername,
1185.33.31 by Martin Pool
Make annotate cope better with revisions committed without a valid
1159
                          config.extract_email_address, 'Jane Tester')
2533.1.1 by James Westby
Fix TreeConfig to return values from sections.
1160
3063.3.2 by Lukáš Lalinský
Move the name and e-mail address extraction logic to config.parse_username.
1161
    def test_parse_username(self):
1162
        self.assertEqual(('', 'jdoe@example.com'),
1163
                         config.parse_username('jdoe@example.com'))
1164
        self.assertEqual(('', 'jdoe@example.com'),
1165
                         config.parse_username('<jdoe@example.com>'))
1166
        self.assertEqual(('John Doe', 'jdoe@example.com'),
1167
                         config.parse_username('John Doe <jdoe@example.com>'))
1168
        self.assertEqual(('John Doe', ''),
1169
                         config.parse_username('John Doe'))
3063.3.3 by Lukáš Lalinský
Add one more test for config.parse_username().
1170
        self.assertEqual(('John Doe', 'jdoe@example.com'),
1171
                         config.parse_username('John Doe jdoe@example.com'))
2562.1.2 by John Arbash Meinel
Clean up whitespace
1172
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
1173
class TestTreeConfig(tests.TestCaseWithTransport):
2533.1.1 by James Westby
Fix TreeConfig to return values from sections.
1174
1175
    def test_get_value(self):
1176
        """Test that retreiving a value from a section is possible"""
1177
        branch = self.make_branch('.')
1178
        tree_config = config.TreeConfig(branch)
1179
        tree_config.set_option('value', 'key', 'SECTION')
1180
        tree_config.set_option('value2', 'key2')
1181
        tree_config.set_option('value3-top', 'key3')
1182
        tree_config.set_option('value3-section', 'key3', 'SECTION')
1183
        value = tree_config.get_option('key', 'SECTION')
1184
        self.assertEqual(value, 'value')
1185
        value = tree_config.get_option('key2')
1186
        self.assertEqual(value, 'value2')
1187
        self.assertEqual(tree_config.get_option('non-existant'), None)
1188
        value = tree_config.get_option('non-existant', 'SECTION')
1189
        self.assertEqual(value, None)
1190
        value = tree_config.get_option('non-existant', default='default')
1191
        self.assertEqual(value, 'default')
1192
        self.assertEqual(tree_config.get_option('key2', 'NOSECTION'), None)
1193
        value = tree_config.get_option('key2', 'NOSECTION', default='default')
1194
        self.assertEqual(value, 'default')
1195
        value = tree_config.get_option('key3')
1196
        self.assertEqual(value, 'value3-top')
1197
        value = tree_config.get_option('key3', 'SECTION')
1198
        self.assertEqual(value, 'value3-section')
2900.2.3 by Vincent Ladeuil
Credentials matching implementation.
1199
1200
3242.1.2 by Aaron Bentley
Turn BzrDirConfig into TransportConfig, reduce code duplication
1201
class TestTransportConfig(tests.TestCaseWithTransport):
3242.1.1 by Aaron Bentley
Implement BzrDir configuration
1202
1203
    def test_get_value(self):
1204
        """Test that retreiving a value from a section is possible"""
3242.1.2 by Aaron Bentley
Turn BzrDirConfig into TransportConfig, reduce code duplication
1205
        bzrdir_config = config.TransportConfig(transport.get_transport('.'),
1206
                                               'control.conf')
3242.1.1 by Aaron Bentley
Implement BzrDir configuration
1207
        bzrdir_config.set_option('value', 'key', 'SECTION')
1208
        bzrdir_config.set_option('value2', 'key2')
1209
        bzrdir_config.set_option('value3-top', 'key3')
1210
        bzrdir_config.set_option('value3-section', 'key3', 'SECTION')
1211
        value = bzrdir_config.get_option('key', 'SECTION')
1212
        self.assertEqual(value, 'value')
1213
        value = bzrdir_config.get_option('key2')
1214
        self.assertEqual(value, 'value2')
1215
        self.assertEqual(bzrdir_config.get_option('non-existant'), None)
1216
        value = bzrdir_config.get_option('non-existant', 'SECTION')
1217
        self.assertEqual(value, None)
1218
        value = bzrdir_config.get_option('non-existant', default='default')
1219
        self.assertEqual(value, 'default')
1220
        self.assertEqual(bzrdir_config.get_option('key2', 'NOSECTION'), None)
1221
        value = bzrdir_config.get_option('key2', 'NOSECTION',
1222
                                         default='default')
1223
        self.assertEqual(value, 'default')
1224
        value = bzrdir_config.get_option('key3')
1225
        self.assertEqual(value, 'value3-top')
1226
        value = bzrdir_config.get_option('key3', 'SECTION')
1227
        self.assertEqual(value, 'value3-section')
1228
3242.3.11 by Aaron Bentley
Clean up BzrDirConfig usage
1229
    def test_set_unset_default_stack_on(self):
1230
        my_dir = self.make_bzrdir('.')
4288.1.3 by Robert Collins
Fix BzrDirConfig tests.
1231
        bzrdir_config = config.BzrDirConfig(my_dir)
3242.3.11 by Aaron Bentley
Clean up BzrDirConfig usage
1232
        self.assertIs(None, bzrdir_config.get_default_stack_on())
1233
        bzrdir_config.set_default_stack_on('Foo')
3242.3.14 by Aaron Bentley
Make BzrDirConfig use TransportConfig
1234
        self.assertEqual('Foo', bzrdir_config._config.get_option(
1235
                         'default_stack_on'))
3242.3.11 by Aaron Bentley
Clean up BzrDirConfig usage
1236
        self.assertEqual('Foo', bzrdir_config.get_default_stack_on())
1237
        bzrdir_config.set_default_stack_on(None)
1238
        self.assertIs(None, bzrdir_config.get_default_stack_on())
1239
3242.1.1 by Aaron Bentley
Implement BzrDir configuration
1240
2900.2.5 by Vincent Ladeuil
ake ftp aware of authentication config.
1241
class TestAuthenticationConfigFile(tests.TestCase):
2900.2.14 by Vincent Ladeuil
More tests.
1242
    """Test the authentication.conf file matching"""
2900.2.3 by Vincent Ladeuil
Credentials matching implementation.
1243
1244
    def _got_user_passwd(self, expected_user, expected_password,
1245
                         config, *args, **kwargs):
1246
        credentials = config.get_credentials(*args, **kwargs)
1247
        if credentials is None:
1248
            user = None
1249
            password = None
1250
        else:
1251
            user = credentials['user']
1252
            password = credentials['password']
1253
        self.assertEquals(expected_user, user)
1254
        self.assertEquals(expected_password, password)
1255
2978.5.1 by John Arbash Meinel
Fix bug #162494, 'bzr register-branch' needs proper auth handling.
1256
    def test_empty_config(self):
2900.2.3 by Vincent Ladeuil
Credentials matching implementation.
1257
        conf = config.AuthenticationConfig(_file=StringIO())
1258
        self.assertEquals({}, conf._get_config())
1259
        self._got_user_passwd(None, None, conf, 'http', 'foo.net')
1260
3418.2.1 by Vincent Ladeuil
Fix #217650 by catching declarations outside sections.
1261
    def test_missing_auth_section_header(self):
1262
        conf = config.AuthenticationConfig(_file=StringIO('foo = bar'))
1263
        self.assertRaises(ValueError, conf.get_credentials, 'ftp', 'foo.net')
1264
1265
    def test_auth_section_header_not_closed(self):
2900.2.3 by Vincent Ladeuil
Credentials matching implementation.
1266
        conf = config.AuthenticationConfig(_file=StringIO('[DEF'))
1267
        self.assertRaises(errors.ParseConfigError, conf._get_config)
2900.2.15 by Vincent Ladeuil
AuthenticationConfig can be queried for logins too (first step).
1268
3418.2.1 by Vincent Ladeuil
Fix #217650 by catching declarations outside sections.
1269
    def test_auth_value_not_boolean(self):
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
1270
        conf = config.AuthenticationConfig(_file=StringIO(
1271
                """[broken]
1272
scheme=ftp
1273
user=joe
2900.2.15 by Vincent Ladeuil
AuthenticationConfig can be queried for logins too (first step).
1274
verify_certificates=askme # Error: Not a boolean
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
1275
"""))
1276
        self.assertRaises(ValueError, conf.get_credentials, 'ftp', 'foo.net')
3418.2.1 by Vincent Ladeuil
Fix #217650 by catching declarations outside sections.
1277
1278
    def test_auth_value_not_int(self):
2900.2.22 by Vincent Ladeuil
Polishing.
1279
        conf = config.AuthenticationConfig(_file=StringIO(
1280
                """[broken]
1281
scheme=ftp
1282
user=joe
1283
port=port # Error: Not an int
1284
"""))
1285
        self.assertRaises(ValueError, conf.get_credentials, 'ftp', 'foo.net')
2900.2.3 by Vincent Ladeuil
Credentials matching implementation.
1286
3757.3.1 by Vincent Ladeuil
Add credential stores plugging.
1287
    def test_unknown_password_encoding(self):
1288
        conf = config.AuthenticationConfig(_file=StringIO(
1289
                """[broken]
1290
scheme=ftp
1291
user=joe
1292
password_encoding=unknown
1293
"""))
1294
        self.assertRaises(ValueError, conf.get_password,
1295
                          'ftp', 'foo.net', 'joe')
1296
2900.2.3 by Vincent Ladeuil
Credentials matching implementation.
1297
    def test_credentials_for_scheme_host(self):
1298
        conf = config.AuthenticationConfig(_file=StringIO(
1299
                """# Identity on foo.net
1300
[ftp definition]
1301
scheme=ftp
1302
host=foo.net
1303
user=joe
1304
password=secret-pass
1305
"""))
1306
        # Basic matching
1307
        self._got_user_passwd('joe', 'secret-pass', conf, 'ftp', 'foo.net')
1308
        # different scheme
1309
        self._got_user_passwd(None, None, conf, 'http', 'foo.net')
1310
        # different host
1311
        self._got_user_passwd(None, None, conf, 'ftp', 'bar.net')
1312
1313
    def test_credentials_for_host_port(self):
1314
        conf = config.AuthenticationConfig(_file=StringIO(
1315
                """# Identity on foo.net
1316
[ftp definition]
1317
scheme=ftp
1318
port=10021
1319
host=foo.net
1320
user=joe
1321
password=secret-pass
1322
"""))
1323
        # No port
1324
        self._got_user_passwd('joe', 'secret-pass',
1325
                              conf, 'ftp', 'foo.net', port=10021)
1326
        # different port
1327
        self._got_user_passwd(None, None, conf, 'ftp', 'foo.net')
1328
1329
    def test_for_matching_host(self):
1330
        conf = config.AuthenticationConfig(_file=StringIO(
1331
                """# Identity on foo.net
1332
[sourceforge]
1333
scheme=bzr
1334
host=bzr.sf.net
1335
user=joe
1336
password=joepass
1337
[sourceforge domain]
1338
scheme=bzr
1339
host=.bzr.sf.net
1340
user=georges
1341
password=bendover
1342
"""))
1343
        # matching domain
1344
        self._got_user_passwd('georges', 'bendover',
1345
                              conf, 'bzr', 'foo.bzr.sf.net')
1346
        # phishing attempt
1347
        self._got_user_passwd(None, None,
1348
                              conf, 'bzr', 'bbzr.sf.net')
1349
1350
    def test_for_matching_host_None(self):
1351
        conf = config.AuthenticationConfig(_file=StringIO(
1352
                """# Identity on foo.net
1353
[catchup bzr]
1354
scheme=bzr
1355
user=joe
1356
password=joepass
1357
[DEFAULT]
1358
user=georges
1359
password=bendover
1360
"""))
1361
        # match no host
1362
        self._got_user_passwd('joe', 'joepass',
1363
                              conf, 'bzr', 'quux.net')
1364
        # no host but different scheme
1365
        self._got_user_passwd('georges', 'bendover',
1366
                              conf, 'ftp', 'quux.net')
1367
1368
    def test_credentials_for_path(self):
1369
        conf = config.AuthenticationConfig(_file=StringIO(
1370
                """
1371
[http dir1]
1372
scheme=http
1373
host=bar.org
1374
path=/dir1
1375
user=jim
1376
password=jimpass
1377
[http dir2]
1378
scheme=http
1379
host=bar.org
1380
path=/dir2
1381
user=georges
1382
password=bendover
1383
"""))
1384
        # no path no dice
1385
        self._got_user_passwd(None, None,
1386
                              conf, 'http', host='bar.org', path='/dir3')
1387
        # matching path
1388
        self._got_user_passwd('georges', 'bendover',
1389
                              conf, 'http', host='bar.org', path='/dir2')
1390
        # matching subdir
1391
        self._got_user_passwd('jim', 'jimpass',
1392
                              conf, 'http', host='bar.org',path='/dir1/subdir')
1393
1394
    def test_credentials_for_user(self):
1395
        conf = config.AuthenticationConfig(_file=StringIO(
1396
                """
1397
[with user]
1398
scheme=http
1399
host=bar.org
1400
user=jim
1401
password=jimpass
1402
"""))
1403
        # Get user
1404
        self._got_user_passwd('jim', 'jimpass',
1405
                              conf, 'http', 'bar.org')
1406
        # Get same user
1407
        self._got_user_passwd('jim', 'jimpass',
1408
                              conf, 'http', 'bar.org', user='jim')
1409
        # Don't get a different user if one is specified
1410
        self._got_user_passwd(None, None,
1411
                              conf, 'http', 'bar.org', user='georges')
1412
3418.4.1 by Vincent Ladeuil
Reproduce bug 199440.
1413
    def test_credentials_for_user_without_password(self):
1414
        conf = config.AuthenticationConfig(_file=StringIO(
1415
                """
1416
[without password]
1417
scheme=http
1418
host=bar.org
1419
user=jim
1420
"""))
1421
        # Get user but no password
1422
        self._got_user_passwd('jim', None,
1423
                              conf, 'http', 'bar.org')
1424
2900.2.3 by Vincent Ladeuil
Credentials matching implementation.
1425
    def test_verify_certificates(self):
1426
        conf = config.AuthenticationConfig(_file=StringIO(
1427
                """
1428
[self-signed]
1429
scheme=https
1430
host=bar.org
1431
user=jim
1432
password=jimpass
1433
verify_certificates=False
1434
[normal]
1435
scheme=https
1436
host=foo.net
1437
user=georges
1438
password=bendover
1439
"""))
1440
        credentials = conf.get_credentials('https', 'bar.org')
1441
        self.assertEquals(False, credentials.get('verify_certificates'))
1442
        credentials = conf.get_credentials('https', 'foo.net')
1443
        self.assertEquals(True, credentials.get('verify_certificates'))
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
1444
3777.1.10 by Aaron Bentley
Ensure credentials are stored
1445
1446
class TestAuthenticationStorage(tests.TestCaseInTempDir):
1447
3777.1.8 by Aaron Bentley
Commit work-in-progress
1448
    def test_set_credentials(self):
3777.1.10 by Aaron Bentley
Ensure credentials are stored
1449
        conf = config.AuthenticationConfig()
3777.3.2 by Aaron Bentley
Reverse order of scheme and password
1450
        conf.set_credentials('name', 'host', 'user', 'scheme', 'password',
4081.1.1 by Jean-Francois Roy
A 'realm' optional argument was added to the get_credentials and set_credentials
1451
        99, path='/foo', verify_certificates=False, realm='realm')
3777.1.8 by Aaron Bentley
Commit work-in-progress
1452
        credentials = conf.get_credentials(host='host', scheme='scheme',
4081.1.1 by Jean-Francois Roy
A 'realm' optional argument was added to the get_credentials and set_credentials
1453
                                           port=99, path='/foo',
1454
                                           realm='realm')
3777.1.10 by Aaron Bentley
Ensure credentials are stored
1455
        CREDENTIALS = {'name': 'name', 'user': 'user', 'password': 'password',
4107.1.8 by Jean-Francois Roy
Updated test_config to account for the new credentials keys.
1456
                       'verify_certificates': False, 'scheme': 'scheme', 
1457
                       'host': 'host', 'port': 99, 'path': '/foo', 
1458
                       'realm': 'realm'}
3777.1.10 by Aaron Bentley
Ensure credentials are stored
1459
        self.assertEqual(CREDENTIALS, credentials)
1460
        credentials_from_disk = config.AuthenticationConfig().get_credentials(
4081.1.1 by Jean-Francois Roy
A 'realm' optional argument was added to the get_credentials and set_credentials
1461
            host='host', scheme='scheme', port=99, path='/foo', realm='realm')
3777.1.10 by Aaron Bentley
Ensure credentials are stored
1462
        self.assertEqual(CREDENTIALS, credentials_from_disk)
3777.1.8 by Aaron Bentley
Commit work-in-progress
1463
3777.1.11 by Aaron Bentley
Ensure changed-name updates clear old values
1464
    def test_reset_credentials_different_name(self):
1465
        conf = config.AuthenticationConfig()
3777.3.2 by Aaron Bentley
Reverse order of scheme and password
1466
        conf.set_credentials('name', 'host', 'user', 'scheme', 'password'),
1467
        conf.set_credentials('name2', 'host', 'user2', 'scheme', 'password'),
3777.1.11 by Aaron Bentley
Ensure changed-name updates clear old values
1468
        self.assertIs(None, conf._get_config().get('name'))
1469
        credentials = conf.get_credentials(host='host', scheme='scheme')
1470
        CREDENTIALS = {'name': 'name2', 'user': 'user2', 'password':
4107.1.8 by Jean-Francois Roy
Updated test_config to account for the new credentials keys.
1471
                       'password', 'verify_certificates': True, 
1472
                       'scheme': 'scheme', 'host': 'host', 'port': None, 
1473
                       'path': None, 'realm': None}
3777.1.11 by Aaron Bentley
Ensure changed-name updates clear old values
1474
        self.assertEqual(CREDENTIALS, credentials)
1475
2900.2.5 by Vincent Ladeuil
ake ftp aware of authentication config.
1476
2900.2.14 by Vincent Ladeuil
More tests.
1477
class TestAuthenticationConfig(tests.TestCase):
1478
    """Test AuthenticationConfig behaviour"""
1479
4222.3.1 by Jelmer Vernooij
Mention password when checking default prompt.
1480
    def _check_default_password_prompt(self, expected_prompt_format, scheme,
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
1481
                                       host=None, port=None, realm=None,
1482
                                       path=None):
2900.2.14 by Vincent Ladeuil
More tests.
1483
        if host is None:
1484
            host = 'bar.org'
1485
        user, password = 'jim', 'precious'
1486
        expected_prompt = expected_prompt_format % {
1487
            'scheme': scheme, 'host': host, 'port': port,
1488
            'user': user, 'realm': realm}
1489
1490
        stdout = tests.StringIOWrapper()
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
1491
        stderr = tests.StringIOWrapper()
2900.2.14 by Vincent Ladeuil
More tests.
1492
        ui.ui_factory = tests.TestUIFactory(stdin=password + '\n',
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
1493
                                            stdout=stdout, stderr=stderr)
2900.2.14 by Vincent Ladeuil
More tests.
1494
        # We use an empty conf so that the user is always prompted
1495
        conf = config.AuthenticationConfig()
1496
        self.assertEquals(password,
1497
                          conf.get_password(scheme, host, user, port=port,
1498
                                            realm=realm, path=path))
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
1499
        self.assertEquals(expected_prompt, stderr.getvalue())
1500
        self.assertEquals('', stdout.getvalue())
2900.2.14 by Vincent Ladeuil
More tests.
1501
4222.3.2 by Jelmer Vernooij
Prompt for user names if they are not in the configuration.
1502
    def _check_default_username_prompt(self, expected_prompt_format, scheme,
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
1503
                                       host=None, port=None, realm=None,
1504
                                       path=None):
4222.3.2 by Jelmer Vernooij
Prompt for user names if they are not in the configuration.
1505
        if host is None:
1506
            host = 'bar.org'
1507
        username = 'jim'
1508
        expected_prompt = expected_prompt_format % {
1509
            'scheme': scheme, 'host': host, 'port': port,
1510
            'realm': realm}
1511
        stdout = tests.StringIOWrapper()
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
1512
        stderr = tests.StringIOWrapper()
4222.3.2 by Jelmer Vernooij
Prompt for user names if they are not in the configuration.
1513
        ui.ui_factory = tests.TestUIFactory(stdin=username+ '\n',
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
1514
                                            stdout=stdout, stderr=stderr)
4222.3.2 by Jelmer Vernooij
Prompt for user names if they are not in the configuration.
1515
        # We use an empty conf so that the user is always prompted
1516
        conf = config.AuthenticationConfig()
4222.3.5 by Jelmer Vernooij
Fix test.
1517
        self.assertEquals(username, conf.get_user(scheme, host, port=port,
1518
                          realm=realm, path=path, ask=True))
4368.3.1 by Vincent Ladeuil
Use stderr for UI prompt to address bug #376582.
1519
        self.assertEquals(expected_prompt, stderr.getvalue())
1520
        self.assertEquals('', stdout.getvalue())
4222.3.2 by Jelmer Vernooij
Prompt for user names if they are not in the configuration.
1521
1522
    def test_username_defaults_prompts(self):
1523
        # HTTP prompts can't be tested here, see test_http.py
1524
        self._check_default_username_prompt('FTP %(host)s username: ', 'ftp')
1525
        self._check_default_username_prompt(
1526
            'FTP %(host)s:%(port)d username: ', 'ftp', port=10020)
1527
        self._check_default_username_prompt(
1528
            'SSH %(host)s:%(port)d username: ', 'ssh', port=12345)
1529
4222.3.11 by Jelmer Vernooij
Add test to make sure the default= parameter works.
1530
    def test_username_default_no_prompt(self):
1531
        conf = config.AuthenticationConfig()
4304.2.1 by Vincent Ladeuil
Fix bug #367726 by reverting some default user handling introduced
1532
        self.assertEquals(None,
4222.3.11 by Jelmer Vernooij
Add test to make sure the default= parameter works.
1533
            conf.get_user('ftp', 'example.com'))
4304.2.1 by Vincent Ladeuil
Fix bug #367726 by reverting some default user handling introduced
1534
        self.assertEquals("explicitdefault",
4222.3.11 by Jelmer Vernooij
Add test to make sure the default= parameter works.
1535
            conf.get_user('ftp', 'example.com', default="explicitdefault"))
1536
4222.3.1 by Jelmer Vernooij
Mention password when checking default prompt.
1537
    def test_password_default_prompts(self):
2900.2.19 by Vincent Ladeuil
Mention proxy and https in the password prompts, with tests.
1538
        # HTTP prompts can't be tested here, see test_http.py
4222.3.1 by Jelmer Vernooij
Mention password when checking default prompt.
1539
        self._check_default_password_prompt(
1540
            'FTP %(user)s@%(host)s password: ', 'ftp')
1541
        self._check_default_password_prompt(
1542
            'FTP %(user)s@%(host)s:%(port)d password: ', 'ftp', port=10020)
1543
        self._check_default_password_prompt(
1544
            'SSH %(user)s@%(host)s:%(port)d password: ', 'ssh', port=12345)
2900.2.14 by Vincent Ladeuil
More tests.
1545
        # SMTP port handling is a bit special (it's handled if embedded in the
1546
        # host too)
2900.2.22 by Vincent Ladeuil
Polishing.
1547
        # FIXME: should we: forbid that, extend it to other schemes, leave
1548
        # things as they are that's fine thank you ?
4222.3.1 by Jelmer Vernooij
Mention password when checking default prompt.
1549
        self._check_default_password_prompt('SMTP %(user)s@%(host)s password: ',
4304.2.1 by Vincent Ladeuil
Fix bug #367726 by reverting some default user handling introduced
1550
                                            'smtp')
4222.3.1 by Jelmer Vernooij
Mention password when checking default prompt.
1551
        self._check_default_password_prompt('SMTP %(user)s@%(host)s password: ',
4304.2.1 by Vincent Ladeuil
Fix bug #367726 by reverting some default user handling introduced
1552
                                            'smtp', host='bar.org:10025')
4222.3.1 by Jelmer Vernooij
Mention password when checking default prompt.
1553
        self._check_default_password_prompt(
2900.2.14 by Vincent Ladeuil
More tests.
1554
            'SMTP %(user)s@%(host)s:%(port)d password: ',
1555
            'smtp', port=10025)
1556
3420.1.2 by Vincent Ladeuil
Fix bug #203186 by ignoring passwords for ssh and warning user.
1557
    def test_ssh_password_emits_warning(self):
1558
        conf = config.AuthenticationConfig(_file=StringIO(
1559
                """
1560
[ssh with password]
1561
scheme=ssh
1562
host=bar.org
1563
user=jim
1564
password=jimpass
1565
"""))
1566
        entered_password = 'typed-by-hand'
1567
        stdout = tests.StringIOWrapper()
4449.3.30 by Martin Pool
Tweaks to test_config ui factory use
1568
        stderr = tests.StringIOWrapper()
3420.1.2 by Vincent Ladeuil
Fix bug #203186 by ignoring passwords for ssh and warning user.
1569
        ui.ui_factory = tests.TestUIFactory(stdin=entered_password + '\n',
4449.3.30 by Martin Pool
Tweaks to test_config ui factory use
1570
                                            stdout=stdout, stderr=stderr)
3420.1.2 by Vincent Ladeuil
Fix bug #203186 by ignoring passwords for ssh and warning user.
1571
1572
        # Since the password defined in the authentication config is ignored,
1573
        # the user is prompted
1574
        self.assertEquals(entered_password,
1575
                          conf.get_password('ssh', 'bar.org', user='jim'))
1576
        self.assertContainsRe(
1577
            self._get_log(keep_log_file=True),
1578
            'password ignored in section \[ssh with password\]')
1579
3420.1.3 by Vincent Ladeuil
John's review feedback.
1580
    def test_ssh_without_password_doesnt_emit_warning(self):
1581
        conf = config.AuthenticationConfig(_file=StringIO(
1582
                """
1583
[ssh with password]
1584
scheme=ssh
1585
host=bar.org
1586
user=jim
1587
"""))
1588
        entered_password = 'typed-by-hand'
1589
        stdout = tests.StringIOWrapper()
4449.3.30 by Martin Pool
Tweaks to test_config ui factory use
1590
        stderr = tests.StringIOWrapper()
3420.1.3 by Vincent Ladeuil
John's review feedback.
1591
        ui.ui_factory = tests.TestUIFactory(stdin=entered_password + '\n',
4449.3.30 by Martin Pool
Tweaks to test_config ui factory use
1592
                                            stdout=stdout,
1593
                                            stderr=stderr)
3420.1.3 by Vincent Ladeuil
John's review feedback.
1594
1595
        # Since the password defined in the authentication config is ignored,
1596
        # the user is prompted
1597
        self.assertEquals(entered_password,
1598
                          conf.get_password('ssh', 'bar.org', user='jim'))
3420.1.4 by Vincent Ladeuil
Fix comment.
1599
        # No warning shoud be emitted since there is no password. We are only
1600
        # providing "user".
3420.1.3 by Vincent Ladeuil
John's review feedback.
1601
        self.assertNotContainsRe(
1602
            self._get_log(keep_log_file=True),
1603
            'password ignored in section \[ssh with password\]')
1604
4283.1.3 by Jelmer Vernooij
Add test to make sure AuthenticationConfig queries for fallback credentials.
1605
    def test_uses_fallback_stores(self):
4283.2.1 by Vincent Ladeuil
Add a test and cleanup some PEP8 issues.
1606
        self._old_cs_registry = config.credential_store_registry
4283.1.3 by Jelmer Vernooij
Add test to make sure AuthenticationConfig queries for fallback credentials.
1607
        def restore():
4283.2.1 by Vincent Ladeuil
Add a test and cleanup some PEP8 issues.
1608
            config.credential_store_registry = self._old_cs_registry
4283.1.3 by Jelmer Vernooij
Add test to make sure AuthenticationConfig queries for fallback credentials.
1609
        self.addCleanup(restore)
1610
        config.credential_store_registry = config.CredentialStoreRegistry()
1611
        store = StubCredentialStore()
1612
        store.add_credentials("http", "example.com", "joe", "secret")
1613
        config.credential_store_registry.register("stub", store, fallback=True)
1614
        conf = config.AuthenticationConfig(_file=StringIO())
1615
        creds = conf.get_credentials("http", "example.com")
1616
        self.assertEquals("joe", creds["user"])
1617
        self.assertEquals("secret", creds["password"])
1618
2900.2.14 by Vincent Ladeuil
More tests.
1619
4283.1.2 by Jelmer Vernooij
Add tests, NEWS item.
1620
class StubCredentialStore(config.CredentialStore):
1621
1622
    def __init__(self):
1623
        self._username = {}
1624
        self._password = {}
1625
1626
    def add_credentials(self, scheme, host, user, password=None):
1627
        self._username[(scheme, host)] = user
1628
        self._password[(scheme, host)] = password
1629
1630
    def get_credentials(self, scheme, host, port=None, user=None,
1631
        path=None, realm=None):
4283.2.1 by Vincent Ladeuil
Add a test and cleanup some PEP8 issues.
1632
        key = (scheme, host)
4283.1.2 by Jelmer Vernooij
Add tests, NEWS item.
1633
        if not key in self._username:
1634
            return None
4283.2.1 by Vincent Ladeuil
Add a test and cleanup some PEP8 issues.
1635
        return { "scheme": scheme, "host": host, "port": port,
4283.1.2 by Jelmer Vernooij
Add tests, NEWS item.
1636
                "user": self._username[key], "password": self._password[key]}
1637
1638
1639
class CountingCredentialStore(config.CredentialStore):
1640
1641
    def __init__(self):
1642
        self._calls = 0
1643
1644
    def get_credentials(self, scheme, host, port=None, user=None,
1645
        path=None, realm=None):
1646
        self._calls += 1
1647
        return None
1648
1649
3757.3.1 by Vincent Ladeuil
Add credential stores plugging.
1650
class TestCredentialStoreRegistry(tests.TestCase):
1651
1652
    def _get_cs_registry(self):
1653
        return config.credential_store_registry
1654
1655
    def test_default_credential_store(self):
1656
        r = self._get_cs_registry()
1657
        default = r.get_credential_store(None)
1658
        self.assertIsInstance(default, config.PlainTextCredentialStore)
1659
1660
    def test_unknown_credential_store(self):
1661
        r = self._get_cs_registry()
1662
        # It's hard to imagine someone creating a credential store named
1663
        # 'unknown' so we use that as an never registered key.
1664
        self.assertRaises(KeyError, r.get_credential_store, 'unknown')
1665
4283.1.2 by Jelmer Vernooij
Add tests, NEWS item.
1666
    def test_fallback_none_registered(self):
1667
        r = config.CredentialStoreRegistry()
4283.2.1 by Vincent Ladeuil
Add a test and cleanup some PEP8 issues.
1668
        self.assertEquals(None,
1669
                          r.get_fallback_credentials("http", "example.com"))
4283.1.2 by Jelmer Vernooij
Add tests, NEWS item.
1670
1671
    def test_register(self):
1672
        r = config.CredentialStoreRegistry()
1673
        r.register("stub", StubCredentialStore(), fallback=False)
1674
        r.register("another", StubCredentialStore(), fallback=True)
1675
        self.assertEquals(["another", "stub"], r.keys())
1676
1677
    def test_register_lazy(self):
1678
        r = config.CredentialStoreRegistry()
4283.2.1 by Vincent Ladeuil
Add a test and cleanup some PEP8 issues.
1679
        r.register_lazy("stub", "bzrlib.tests.test_config",
1680
                        "StubCredentialStore", fallback=False)
4283.1.2 by Jelmer Vernooij
Add tests, NEWS item.
1681
        self.assertEquals(["stub"], r.keys())
4283.2.1 by Vincent Ladeuil
Add a test and cleanup some PEP8 issues.
1682
        self.assertIsInstance(r.get_credential_store("stub"),
1683
                              StubCredentialStore)
4283.1.2 by Jelmer Vernooij
Add tests, NEWS item.
1684
1685
    def test_is_fallback(self):
1686
        r = config.CredentialStoreRegistry()
1687
        r.register("stub1", None, fallback=False)
1688
        r.register("stub2", None, fallback=True)
1689
        self.assertEquals(False, r.is_fallback("stub1"))
1690
        self.assertEquals(True, r.is_fallback("stub2"))
1691
1692
    def test_no_fallback(self):
1693
        r = config.CredentialStoreRegistry()
1694
        store = CountingCredentialStore()
1695
        r.register("count", store, fallback=False)
4283.2.1 by Vincent Ladeuil
Add a test and cleanup some PEP8 issues.
1696
        self.assertEquals(None,
1697
                          r.get_fallback_credentials("http", "example.com"))
4283.1.2 by Jelmer Vernooij
Add tests, NEWS item.
1698
        self.assertEquals(0, store._calls)
1699
1700
    def test_fallback_credentials(self):
1701
        r = config.CredentialStoreRegistry()
1702
        store = StubCredentialStore()
4283.2.1 by Vincent Ladeuil
Add a test and cleanup some PEP8 issues.
1703
        store.add_credentials("http", "example.com",
1704
                              "somebody", "geheim")
4283.1.2 by Jelmer Vernooij
Add tests, NEWS item.
1705
        r.register("stub", store, fallback=True)
1706
        creds = r.get_fallback_credentials("http", "example.com")
1707
        self.assertEquals("somebody", creds["user"])
1708
        self.assertEquals("geheim", creds["password"])
1709
4283.2.1 by Vincent Ladeuil
Add a test and cleanup some PEP8 issues.
1710
    def test_fallback_first_wins(self):
1711
        r = config.CredentialStoreRegistry()
1712
        stub1 = StubCredentialStore()
1713
        stub1.add_credentials("http", "example.com",
1714
                              "somebody", "stub1")
1715
        r.register("stub1", stub1, fallback=True)
1716
        stub2 = StubCredentialStore()
1717
        stub2.add_credentials("http", "example.com",
1718
                              "somebody", "stub2")
1719
        r.register("stub2", stub1, fallback=True)
1720
        creds = r.get_fallback_credentials("http", "example.com")
1721
        self.assertEquals("somebody", creds["user"])
1722
        self.assertEquals("stub1", creds["password"])
1723
3757.3.1 by Vincent Ladeuil
Add credential stores plugging.
1724
1725
class TestPlainTextCredentialStore(tests.TestCase):
1726
1727
    def test_decode_password(self):
1728
        r = config.credential_store_registry
1729
        plain_text = r.get_credential_store()
1730
        decoded = plain_text.decode_password(dict(password='secret'))
1731
        self.assertEquals('secret', decoded)
1732
1733
2900.2.14 by Vincent Ladeuil
More tests.
1734
# FIXME: Once we have a way to declare authentication to all test servers, we
2900.2.5 by Vincent Ladeuil
ake ftp aware of authentication config.
1735
# can implement generic tests.
2900.2.15 by Vincent Ladeuil
AuthenticationConfig can be queried for logins too (first step).
1736
# test_user_password_in_url
1737
# test_user_in_url_password_from_config
1738
# test_user_in_url_password_prompted
1739
# test_user_in_config
1740
# test_user_getpass.getuser
1741
# test_user_prompted ?
2900.2.5 by Vincent Ladeuil
ake ftp aware of authentication config.
1742
class TestAuthenticationRing(tests.TestCaseWithTransport):
1743
    pass