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