~bzr-pqm/bzr/bzr.dev

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