/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2052.3.2 by John Arbash Meinel
Change Copyright .. by Canonical to Copyright ... Canonical
1
# Copyright (C) 2005, 2006 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
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
18
"""Tests for finding and reading the bzr config file[s]."""
19
# import system imports here
1474 by Robert Collins
Merge from Aaron Bentley.
20
from bzrlib.util.configobj.configobj import ConfigObj, ConfigObjError
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
21
from cStringIO import StringIO
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,
1878.1.3 by John Arbash Meinel
some test cleanups
37
    )
1442.1.1 by Robert Collins
move config_dir into bzrlib.config
38
39
1553.6.12 by Erik Bågfors
remove AliasConfig, based on input from abentley
40
sample_long_alias="log -r-15..-1 --line"
2120.6.2 by James Henstridge
remove get_matching_sections() norecurse tests, since that feature is handled in the config policy code now
41
sample_config_text = u"""
42
[DEFAULT]
43
email=Erik B\u00e5gfors <erik@bagfors.nu>
44
editor=vim
45
gpg_signing_command=gnome-gpg
46
log_format=short
47
user_global_option=something
48
[ALIASES]
49
h=help
50
ll=""" + sample_long_alias + "\n"
51
52
53
sample_always_signatures = """
54
[DEFAULT]
55
check_signatures=ignore
56
create_signatures=always
57
"""
58
59
sample_ignore_signatures = """
60
[DEFAULT]
61
check_signatures=require
62
create_signatures=never
63
"""
64
65
sample_maybe_signatures = """
66
[DEFAULT]
67
check_signatures=ignore
68
create_signatures=when-required
69
"""
70
71
sample_branches_text = """
72
[http://www.example.com]
73
# Top level policy
74
email=Robert Collins <robertc@example.org>
2120.6.3 by James Henstridge
add some more tests for getting policy options, and behaviour of get_user_option in the presence of config policies
75
normal_option = normal
76
appendpath_option = append
2120.6.8 by James Henstridge
Change syntax for setting config option policies. Rather than
77
appendpath_option:policy = appendpath
2120.6.3 by James Henstridge
add some more tests for getting policy options, and behaviour of get_user_option in the presence of config policies
78
norecurse_option = norecurse
2120.6.8 by James Henstridge
Change syntax for setting config option policies. Rather than
79
norecurse_option:policy = norecurse
2120.6.2 by James Henstridge
remove get_matching_sections() norecurse tests, since that feature is handled in the config policy code now
80
[http://www.example.com/ignoreparent]
81
# different project: ignore parent dir config
82
ignore_parents=true
83
[http://www.example.com/norecurse]
84
# configuration items that only apply to this dir
85
recurse=false
2120.6.3 by James Henstridge
add some more tests for getting policy options, and behaviour of get_user_option in the presence of config policies
86
normal_option = norecurse
87
[http://www.example.com/dir]
88
appendpath_option = normal
2120.6.2 by James Henstridge
remove get_matching_sections() norecurse tests, since that feature is handled in the config policy code now
89
[/b/]
90
check_signatures=require
91
# test trailing / matching with no children
92
[/a/]
93
check_signatures=check-available
94
gpg_signing_command=false
95
user_local_option=local
96
# test trailing / matching
97
[/a/*]
98
#subdirs will match but not the parent
99
[/a/c]
100
check_signatures=ignore
101
post_commit=bzrlib.tests.test_config.post_commit
102
#testing explicit beats globs
103
"""
1553.6.3 by Erik Bågfors
tests for AliasesConfig
104
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
105
1474 by Robert Collins
Merge from Aaron Bentley.
106
class InstrumentedConfigObj(object):
107
    """A config obj look-enough-alike to record calls made to it."""
108
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
109
    def __contains__(self, thing):
110
        self._calls.append(('__contains__', thing))
111
        return False
112
113
    def __getitem__(self, key):
114
        self._calls.append(('__getitem__', key))
115
        return self
116
1551.2.20 by Aaron Bentley
Treated config files as utf-8
117
    def __init__(self, input, encoding=None):
118
        self._calls = [('__init__', input, encoding)]
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
119
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
120
    def __setitem__(self, key, value):
121
        self._calls.append(('__setitem__', key, value))
122
2120.6.4 by James Henstridge
add support for specifying policy when storing options
123
    def __delitem__(self, key):
124
        self._calls.append(('__delitem__', key))
125
126
    def keys(self):
127
        self._calls.append(('keys',))
128
        return []
129
1551.2.49 by abentley
Made ConfigObj output binary-identical files on win32 and *nix
130
    def write(self, arg):
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
131
        self._calls.append(('write',))
132
2120.6.4 by James Henstridge
add support for specifying policy when storing options
133
    def as_bool(self, value):
134
        self._calls.append(('as_bool', value))
135
        return False
136
137
    def get_value(self, section, name):
138
        self._calls.append(('get_value', section, name))
139
        return None
140
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
141
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
142
class FakeBranch(object):
143
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
144
    def __init__(self, base=None, user_id=None):
145
        if base is None:
146
            self.base = "http://example.com/branches/demo"
147
        else:
148
            self.base = base
149
        self.control_files = FakeControlFiles(user_id=user_id)
150
151
    def lock_write(self):
152
        pass
153
154
    def unlock(self):
155
        pass
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
156
157
158
class FakeControlFiles(object):
159
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
160
    def __init__(self, user_id=None):
161
        self.email = user_id
162
        self.files = {}
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
163
1185.65.29 by Robert Collins
Implement final review suggestions.
164
    def get_utf8(self, filename):
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
165
        if filename != 'email':
166
            raise NotImplementedError
167
        if self.email is not None:
168
            return StringIO(self.email)
1185.31.45 by John Arbash Meinel
Refactoring Exceptions found some places where the wrong exception was caught.
169
        raise errors.NoSuchFile(filename)
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
170
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
171
    def get(self, filename):
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
172
        try:
173
            return StringIO(self.files[filename])
174
        except KeyError:
175
            raise errors.NoSuchFile(filename)
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
176
177
    def put(self, filename, fileobj):
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
178
        self.files[filename] = fileobj.read()
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
179
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
180
181
class InstrumentedConfig(config.Config):
182
    """An instrumented config that supplies stubs for template methods."""
183
    
184
    def __init__(self):
185
        super(InstrumentedConfig, self).__init__()
186
        self._calls = []
1442.1.15 by Robert Collins
make getting the signature checking policy a template method
187
        self._signatures = config.CHECK_NEVER
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
188
189
    def _get_user_id(self):
190
        self._calls.append('_get_user_id')
191
        return "Robert Collins <robert.collins@example.org>"
192
1442.1.15 by Robert Collins
make getting the signature checking policy a template method
193
    def _get_signature_checking(self):
194
        self._calls.append('_get_signature_checking')
195
        return self._signatures
196
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
197
1556.2.2 by Aaron Bentley
Fixed get_bool
198
bool_config = """[DEFAULT]
199
active = true
200
inactive = false
201
[UPPERCASE]
202
active = True
203
nonactive = False
204
"""
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
205
class TestConfigObj(tests.TestCase):
1556.2.2 by Aaron Bentley
Fixed get_bool
206
    def test_get_bool(self):
207
        from bzrlib.config import ConfigObj
208
        co = ConfigObj(StringIO(bool_config))
209
        self.assertIs(co.get_bool('DEFAULT', 'active'), True)
210
        self.assertIs(co.get_bool('DEFAULT', 'inactive'), False)
211
        self.assertIs(co.get_bool('UPPERCASE', 'active'), True)
212
        self.assertIs(co.get_bool('UPPERCASE', 'nonactive'), False)
213
214
2900.1.1 by Vincent Ladeuil
215
erroneous_config = """[section] # line 1
216
good=good # line 2
217
[section] # line 3
218
whocares=notme # line 4
219
"""
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
220
class TestConfigObjErrors(tests.TestCase):
2900.1.1 by Vincent Ladeuil
221
222
    def test_duplicate_section_name_error_line(self):
223
        try:
224
            co = ConfigObj(StringIO(erroneous_config), raise_errors=True)
225
        except config.configobj.DuplicateError, e:
226
            self.assertEqual(3, e.line_number)
227
        else:
228
            self.fail('Error in config file not detected')
229
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
230
class TestConfig(tests.TestCase):
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
231
232
    def test_constructs(self):
233
        config.Config()
234
 
235
    def test_no_default_editor(self):
236
        self.assertRaises(NotImplementedError, config.Config().get_editor)
237
238
    def test_user_email(self):
239
        my_config = InstrumentedConfig()
240
        self.assertEqual('robert.collins@example.org', my_config.user_email())
241
        self.assertEqual(['_get_user_id'], my_config._calls)
242
243
    def test_username(self):
244
        my_config = InstrumentedConfig()
245
        self.assertEqual('Robert Collins <robert.collins@example.org>',
246
                         my_config.username())
247
        self.assertEqual(['_get_user_id'], my_config._calls)
1442.1.14 by Robert Collins
Create a default signature checking policy of CHECK_IF_POSSIBLE
248
249
    def test_signatures_default(self):
250
        my_config = config.Config()
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
251
        self.assertFalse(my_config.signature_needed())
1442.1.14 by Robert Collins
Create a default signature checking policy of CHECK_IF_POSSIBLE
252
        self.assertEqual(config.CHECK_IF_POSSIBLE,
253
                         my_config.signature_checking())
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
254
        self.assertEqual(config.SIGN_WHEN_REQUIRED,
255
                         my_config.signing_policy())
1442.1.14 by Robert Collins
Create a default signature checking policy of CHECK_IF_POSSIBLE
256
1442.1.15 by Robert Collins
make getting the signature checking policy a template method
257
    def test_signatures_template_method(self):
258
        my_config = InstrumentedConfig()
259
        self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
260
        self.assertEqual(['_get_signature_checking'], my_config._calls)
261
262
    def test_signatures_template_method_none(self):
263
        my_config = InstrumentedConfig()
264
        my_config._signatures = None
265
        self.assertEqual(config.CHECK_IF_POSSIBLE,
266
                         my_config.signature_checking())
267
        self.assertEqual(['_get_signature_checking'], my_config._calls)
268
1442.1.56 by Robert Collins
gpg_signing_command configuration item
269
    def test_gpg_signing_command_default(self):
270
        my_config = config.Config()
271
        self.assertEqual('gpg', my_config.gpg_signing_command())
272
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
273
    def test_get_user_option_default(self):
274
        my_config = config.Config()
275
        self.assertEqual(None, my_config.get_user_option('no_option'))
276
1472 by Robert Collins
post commit hook, first pass implementation
277
    def test_post_commit_default(self):
278
        my_config = config.Config()
279
        self.assertEqual(None, my_config.post_commit())
280
1553.2.9 by Erik Bågfors
log_formatter => log_format for "named" formatters
281
    def test_log_format_default(self):
1553.2.8 by Erik Bågfors
tests for config log_formatter
282
        my_config = config.Config()
1553.2.9 by Erik Bågfors
log_formatter => log_format for "named" formatters
283
        self.assertEqual('long', my_config.log_format())
1553.2.8 by Erik Bågfors
tests for config log_formatter
284
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
285
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
286
class TestConfigPath(tests.TestCase):
1442.1.1 by Robert Collins
move config_dir into bzrlib.config
287
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
288
    def setUp(self):
289
        super(TestConfigPath, self).setUp()
290
        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
291
        if sys.platform == 'win32':
292
            os.environ['BZR_HOME'] = \
293
                r'C:\Documents and Settings\bogus\Application Data'
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
294
1442.1.1 by Robert Collins
move config_dir into bzrlib.config
295
    def test_config_dir(self):
1185.38.1 by John Arbash Meinel
Adding my win32 patch for moving the home directory.
296
        if sys.platform == 'win32':
297
            self.assertEqual(config.config_dir(), 
1185.31.36 by John Arbash Meinel
Fixup test_config.py to handle new paths
298
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0')
1185.38.1 by John Arbash Meinel
Adding my win32 patch for moving the home directory.
299
        else:
300
            self.assertEqual(config.config_dir(), '/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.
301
302
    def test_config_filename(self):
1185.38.1 by John Arbash Meinel
Adding my win32 patch for moving the home directory.
303
        if sys.platform == 'win32':
304
            self.assertEqual(config.config_filename(), 
1185.31.36 by John Arbash Meinel
Fixup test_config.py to handle new paths
305
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0/bazaar.conf')
1185.38.1 by John Arbash Meinel
Adding my win32 patch for moving the home directory.
306
        else:
307
            self.assertEqual(config.config_filename(),
308
                             '/home/bogus/.bazaar/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.
309
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
310
    def test_branches_config_filename(self):
1185.38.1 by John Arbash Meinel
Adding my win32 patch for moving the home directory.
311
        if sys.platform == 'win32':
312
            self.assertEqual(config.branches_config_filename(), 
1185.31.36 by John Arbash Meinel
Fixup test_config.py to handle new paths
313
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0/branches.conf')
1185.38.1 by John Arbash Meinel
Adding my win32 patch for moving the home directory.
314
        else:
315
            self.assertEqual(config.branches_config_filename(),
316
                             '/home/bogus/.bazaar/branches.conf')
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
317
1770.2.2 by Aaron Bentley
Rename branches.conf to locations.conf
318
    def test_locations_config_filename(self):
319
        if sys.platform == 'win32':
320
            self.assertEqual(config.locations_config_filename(), 
321
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0/locations.conf')
322
        else:
323
            self.assertEqual(config.locations_config_filename(),
324
                             '/home/bogus/.bazaar/locations.conf')
325
2900.2.5 by Vincent Ladeuil
ake ftp aware of authentication config.
326
    def test_authentication_config_filename(self):
327
        if sys.platform == 'win32':
328
            self.assertEqual(config.authentication_config_filename(), 
329
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0/authentication.conf')
330
        else:
331
            self.assertEqual(config.authentication_config_filename(),
332
                             '/home/bogus/.bazaar/authentication.conf')
333
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
334
class TestIniConfig(tests.TestCase):
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
335
336
    def test_contructs(self):
337
        my_config = config.IniBasedConfig("nothing")
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
338
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
    def test_from_fp(self):
1551.2.20 by Aaron Bentley
Treated config files as utf-8
340
        config_file = StringIO(sample_config_text.encode('utf-8'))
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
341
        my_config = config.IniBasedConfig(None)
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
342
        self.failUnless(
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
343
            isinstance(my_config._get_parser(file=config_file),
1474 by Robert Collins
Merge from Aaron Bentley.
344
                        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.
345
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
346
    def test_cached(self):
1551.2.20 by Aaron Bentley
Treated config files as utf-8
347
        config_file = StringIO(sample_config_text.encode('utf-8'))
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
348
        my_config = config.IniBasedConfig(None)
349
        parser = my_config._get_parser(file=config_file)
350
        self.failUnless(my_config._get_parser() is parser)
351
352
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
353
class TestGetConfig(tests.TestCase):
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
354
355
    def test_constructs(self):
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
356
        my_config = config.GlobalConfig()
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_calls_read_filenames(self):
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
359
        # replace the class that is constructured, to check its parameters
1474 by Robert Collins
Merge from Aaron Bentley.
360
        oldparserclass = config.ConfigObj
361
        config.ConfigObj = InstrumentedConfigObj
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
362
        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.
363
        try:
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
364
            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.
365
        finally:
1474 by Robert Collins
Merge from Aaron Bentley.
366
            config.ConfigObj = oldparserclass
367
        self.failUnless(isinstance(parser, InstrumentedConfigObj))
1551.2.20 by Aaron Bentley
Treated config files as utf-8
368
        self.assertEqual(parser._calls, [('__init__', config.config_filename(),
369
                                          '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.
370
371
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
372
class TestBranchConfig(tests.TestCaseWithTransport):
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
373
374
    def test_constructs(self):
375
        branch = FakeBranch()
376
        my_config = config.BranchConfig(branch)
377
        self.assertRaises(TypeError, config.BranchConfig)
378
379
    def test_get_location_config(self):
380
        branch = FakeBranch()
381
        my_config = config.BranchConfig(branch)
382
        location_config = my_config._get_location_config()
383
        self.assertEqual(branch.base, location_config.location)
384
        self.failUnless(location_config is my_config._get_location_config())
385
1770.2.9 by Aaron Bentley
Add Branch.get_config, update BranchConfig() callers
386
    def test_get_config(self):
387
        """The Branch.get_config method works properly"""
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
388
        b = bzrdir.BzrDir.create_standalone_workingtree('.').branch
1770.2.9 by Aaron Bentley
Add Branch.get_config, update BranchConfig() callers
389
        my_config = b.get_config()
390
        self.assertIs(my_config.get_user_option('wacky'), None)
391
        my_config.set_user_option('wacky', 'unlikely')
392
        self.assertEqual(my_config.get_user_option('wacky'), 'unlikely')
393
394
        # Ensure we get the same thing if we start again
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
395
        b2 = branch.Branch.open('.')
1770.2.9 by Aaron Bentley
Add Branch.get_config, update BranchConfig() callers
396
        my_config2 = b2.get_config()
397
        self.assertEqual(my_config2.get_user_option('wacky'), 'unlikely')
398
1824.1.1 by Robert Collins
Add BranchConfig.has_explicit_nickname call.
399
    def test_has_explicit_nickname(self):
400
        b = self.make_branch('.')
401
        self.assertFalse(b.get_config().has_explicit_nickname())
402
        b.nick = 'foo'
403
        self.assertTrue(b.get_config().has_explicit_nickname())
404
1878.1.1 by John Arbash Meinel
Entries in locations.conf should prefer local paths if available (bug #53653)
405
    def test_config_url(self):
406
        """The Branch.get_config will use section that uses a local url"""
407
        branch = self.make_branch('branch')
408
        self.assertEqual('branch', branch.nick)
409
410
        locations = config.locations_config_filename()
411
        config.ensure_config_dir_exists()
412
        local_url = urlutils.local_path_to_url('branch')
413
        open(locations, 'wb').write('[%s]\nnickname = foobar' 
414
                                    % (local_url,))
415
        self.assertEqual('foobar', branch.nick)
416
417
    def test_config_local_path(self):
418
        """The Branch.get_config will use a local system path"""
419
        branch = self.make_branch('branch')
420
        self.assertEqual('branch', branch.nick)
421
422
        locations = config.locations_config_filename()
423
        config.ensure_config_dir_exists()
424
        open(locations, 'wb').write('[%s/branch]\nnickname = barry' 
425
                                    % (osutils.getcwd().encode('utf8'),))
426
        self.assertEqual('barry', branch.nick)
427
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
428
    def test_config_creates_local(self):
429
        """Creating a new entry in config uses a local path."""
2230.3.6 by Aaron Bentley
work in progress bind stuff
430
        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
431
        branch.set_push_location('http://foobar')
432
        locations = config.locations_config_filename()
433
        local_path = osutils.getcwd().encode('utf8')
434
        # Surprisingly ConfigObj doesn't create a trailing newline
435
        self.check_file_contents(locations,
2120.6.8 by James Henstridge
Change syntax for setting config option policies. Rather than
436
            '[%s/branch]\npush_location = http://foobar\npush_location:policy = norecurse' % (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
437
2120.5.4 by Alexander Belchenko
Whitebox test for Config.get_nickname (req. by Aaron Bentley)
438
    def test_autonick_urlencoded(self):
439
        b = self.make_branch('!repo')
440
        self.assertEqual('!repo', b.get_config().get_nickname())
441
1551.15.35 by Aaron Bentley
Warn when setting config values that will be masked (#122286)
442
    def test_warn_if_masked(self):
443
        _warning = trace.warning
444
        warnings = []
445
        def warning(*args):
446
            warnings.append(args[0] % args[1:])
447
448
        def set_option(store, warn_masked=True):
449
            warnings[:] = []
450
            conf.set_user_option('example_option', repr(store), store=store,
451
                                 warn_masked=warn_masked)
452
        def assertWarning(warning):
453
            if warning is None:
454
                self.assertEqual(0, len(warnings))
455
            else:
456
                self.assertEqual(1, len(warnings))
457
                self.assertEqual(warning, warnings[0])
458
        trace.warning = warning
459
        try:
460
            branch = self.make_branch('.')
461
            conf = branch.get_config()
462
            set_option(config.STORE_GLOBAL)
463
            assertWarning(None)
464
            set_option(config.STORE_BRANCH)
465
            assertWarning(None)
466
            set_option(config.STORE_GLOBAL)
467
            assertWarning('Value "4" is masked by "3" from branch.conf')
468
            set_option(config.STORE_GLOBAL, warn_masked=False)
469
            assertWarning(None)
470
            set_option(config.STORE_LOCATION)
471
            assertWarning(None)
472
            set_option(config.STORE_BRANCH)
473
            assertWarning('Value "3" is masked by "0" from locations.conf')
474
            set_option(config.STORE_BRANCH, warn_masked=False)
475
            assertWarning(None)
476
        finally:
477
            trace.warning = _warning
478
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
479
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
480
class TestGlobalConfigItems(tests.TestCase):
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
481
1442.1.2 by Robert Collins
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.
482
    def test_user_id(self):
1551.2.20 by Aaron Bentley
Treated config files as utf-8
483
        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
484
        my_config = config.GlobalConfig()
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
485
        my_config._parser = my_config._get_parser(file=config_file)
1551.2.21 by Aaron Bentley
Formatted unicode config tests as ASCII
486
        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
487
                         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.
488
489
    def test_absent_user_id(self):
490
        config_file = StringIO("")
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
491
        my_config = config.GlobalConfig()
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
492
        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
493
        self.assertEqual(None, my_config._get_user_id())
494
495
    def test_configured_editor(self):
1551.2.20 by Aaron Bentley
Treated config files as utf-8
496
        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
497
        my_config = config.GlobalConfig()
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
498
        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
499
        self.assertEqual("vim", my_config.get_editor())
500
1442.1.17 by Robert Collins
allow global overriding of signature policy to force checking, or (pointless but allowed) to set auto checking
501
    def test_signatures_always(self):
502
        config_file = StringIO(sample_always_signatures)
503
        my_config = config.GlobalConfig()
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
504
        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
505
        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
506
                         my_config.signature_checking())
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
507
        self.assertEqual(config.SIGN_ALWAYS,
508
                         my_config.signing_policy())
1442.1.21 by Robert Collins
create signature_needed() call for commit to trigger creating signatures
509
        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
510
511
    def test_signatures_if_possible(self):
512
        config_file = StringIO(sample_maybe_signatures)
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)
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
515
        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
516
                         my_config.signature_checking())
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
517
        self.assertEqual(config.SIGN_WHEN_REQUIRED,
518
                         my_config.signing_policy())
1442.1.21 by Robert Collins
create signature_needed() call for commit to trigger creating signatures
519
        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
520
1442.1.16 by Robert Collins
allow global overriding of signature policy to never check
521
    def test_signatures_ignore(self):
522
        config_file = StringIO(sample_ignore_signatures)
523
        my_config = config.GlobalConfig()
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
524
        my_config._parser = my_config._get_parser(file=config_file)
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
525
        self.assertEqual(config.CHECK_ALWAYS,
1442.1.16 by Robert Collins
allow global overriding of signature policy to never check
526
                         my_config.signature_checking())
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
527
        self.assertEqual(config.SIGN_NEVER,
528
                         my_config.signing_policy())
1442.1.21 by Robert Collins
create signature_needed() call for commit to trigger creating signatures
529
        self.assertEqual(False, my_config.signature_needed())
1442.1.16 by Robert Collins
allow global overriding of signature policy to never check
530
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
531
    def _get_sample_config(self):
1551.2.20 by Aaron Bentley
Treated config files as utf-8
532
        config_file = StringIO(sample_config_text.encode('utf-8'))
1534.7.154 by Aaron Bentley
Removed changes from bzr.ab 1529..1536
533
        my_config = config.GlobalConfig()
534
        my_config._parser = my_config._get_parser(file=config_file)
535
        return my_config
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
536
1442.1.56 by Robert Collins
gpg_signing_command configuration item
537
    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.
538
        my_config = self._get_sample_config()
1442.1.56 by Robert Collins
gpg_signing_command configuration item
539
        self.assertEqual("gnome-gpg", my_config.gpg_signing_command())
540
        self.assertEqual(False, my_config.signature_needed())
541
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
542
    def _get_empty_config(self):
543
        config_file = StringIO("")
544
        my_config = config.GlobalConfig()
545
        my_config._parser = my_config._get_parser(file=config_file)
546
        return my_config
547
1442.1.59 by Robert Collins
Add re-sign command to generate a digital signature on a single revision.
548
    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.
549
        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.
550
        self.assertEqual("gpg", my_config.gpg_signing_command())
551
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
552
    def test_get_user_option_default(self):
553
        my_config = self._get_empty_config()
554
        self.assertEqual(None, my_config.get_user_option('no_option'))
555
556
    def test_get_user_option_global(self):
557
        my_config = self._get_sample_config()
558
        self.assertEqual("something",
559
                         my_config.get_user_option('user_global_option'))
1472 by Robert Collins
post commit hook, first pass implementation
560
        
561
    def test_post_commit_default(self):
562
        my_config = self._get_sample_config()
563
        self.assertEqual(None, my_config.post_commit())
564
1553.2.9 by Erik Bågfors
log_formatter => log_format for "named" formatters
565
    def test_configured_logformat(self):
1553.2.8 by Erik Bågfors
tests for config log_formatter
566
        my_config = self._get_sample_config()
1553.2.9 by Erik Bågfors
log_formatter => log_format for "named" formatters
567
        self.assertEqual("short", my_config.log_format())
1553.2.8 by Erik Bågfors
tests for config log_formatter
568
1553.6.12 by Erik Bågfors
remove AliasConfig, based on input from abentley
569
    def test_get_alias(self):
570
        my_config = self._get_sample_config()
571
        self.assertEqual('help', my_config.get_alias('h'))
572
573
    def test_get_no_alias(self):
574
        my_config = self._get_sample_config()
575
        self.assertEqual(None, my_config.get_alias('foo'))
576
577
    def test_get_long_alias(self):
578
        my_config = self._get_sample_config()
579
        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.
580
1704.2.18 by Martin Pool
Remove duplicated TestLocationConfig and update previously hidden tests. (#32587)
581
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
582
class TestLocationConfig(tests.TestCaseInTempDir):
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
583
584
    def test_constructs(self):
585
        my_config = config.LocationConfig('http://example.com')
586
        self.assertRaises(TypeError, config.LocationConfig)
587
588
    def test_branch_calls_read_filenames(self):
1474 by Robert Collins
Merge from Aaron Bentley.
589
        # This is testing the correct file names are provided.
590
        # TODO: consolidate with the test for GlobalConfigs filename checks.
591
        #
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
592
        # replace the class that is constructured, to check its parameters
1474 by Robert Collins
Merge from Aaron Bentley.
593
        oldparserclass = config.ConfigObj
594
        config.ConfigObj = InstrumentedConfigObj
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
595
        try:
1770.2.2 by Aaron Bentley
Rename branches.conf to locations.conf
596
            my_config = config.LocationConfig('http://www.example.com')
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
597
            parser = my_config._get_parser()
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
598
        finally:
1474 by Robert Collins
Merge from Aaron Bentley.
599
            config.ConfigObj = oldparserclass
600
        self.failUnless(isinstance(parser, InstrumentedConfigObj))
601
        self.assertEqual(parser._calls,
1770.2.2 by Aaron Bentley
Rename branches.conf to locations.conf
602
                         [('__init__', config.locations_config_filename(),
1704.2.18 by Martin Pool
Remove duplicated TestLocationConfig and update previously hidden tests. (#32587)
603
                           'utf-8')])
1711.4.29 by John Arbash Meinel
Alexander Belchenko, fix test_config to use ensure_config_dir, rather than os.mkdir()
604
        config.ensure_config_dir_exists()
605
        #os.mkdir(config.config_dir())
1770.2.2 by Aaron Bentley
Rename branches.conf to locations.conf
606
        f = file(config.branches_config_filename(), 'wb')
607
        f.write('')
608
        f.close()
609
        oldparserclass = config.ConfigObj
610
        config.ConfigObj = InstrumentedConfigObj
611
        try:
612
            my_config = config.LocationConfig('http://www.example.com')
613
            parser = my_config._get_parser()
614
        finally:
615
            config.ConfigObj = oldparserclass
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
616
617
    def test_get_global_config(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
618
        my_config = config.BranchConfig(FakeBranch('http://example.com'))
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
619
        global_config = my_config._get_global_config()
620
        self.failUnless(isinstance(global_config, config.GlobalConfig))
621
        self.failUnless(global_config is my_config._get_global_config())
622
1993.3.1 by James Henstridge
first go at making location config lookup recursive
623
    def test__get_matching_sections_no_match(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
624
        self.get_branch_config('/')
1993.3.1 by James Henstridge
first go at making location config lookup recursive
625
        self.assertEqual([], self.my_location_config._get_matching_sections())
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
626
        
1993.3.1 by James Henstridge
first go at making location config lookup recursive
627
    def test__get_matching_sections_exact(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
628
        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
629
        self.assertEqual([('http://www.example.com', '')],
1993.3.1 by James Henstridge
first go at making location config lookup recursive
630
                         self.my_location_config._get_matching_sections())
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
631
   
1993.3.1 by James Henstridge
first go at making location config lookup recursive
632
    def test__get_matching_sections_suffix_does_not(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
633
        self.get_branch_config('http://www.example.com-com')
1993.3.1 by James Henstridge
first go at making location config lookup recursive
634
        self.assertEqual([], self.my_location_config._get_matching_sections())
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
635
1993.3.1 by James Henstridge
first go at making location config lookup recursive
636
    def test__get_matching_sections_subdir_recursive(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
637
        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
638
        self.assertEqual([('http://www.example.com', 'com')],
1993.3.1 by James Henstridge
first go at making location config lookup recursive
639
                         self.my_location_config._get_matching_sections())
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
640
1993.3.5 by James Henstridge
add back recurse=False option to config file
641
    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
642
        self.get_branch_config('http://www.example.com/ignoreparent')
643
        self.assertEqual([('http://www.example.com/ignoreparent', '')],
1993.3.1 by James Henstridge
first go at making location config lookup recursive
644
                         self.my_location_config._get_matching_sections())
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
645
1993.3.5 by James Henstridge
add back recurse=False option to config file
646
    def test__get_matching_sections_ignoreparent_subdir(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
647
        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
648
            'http://www.example.com/ignoreparent/childbranch')
649
        self.assertEqual([('http://www.example.com/ignoreparent', 'childbranch')],
1993.3.1 by James Henstridge
first go at making location config lookup recursive
650
                         self.my_location_config._get_matching_sections())
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
651
1993.3.1 by James Henstridge
first go at making location config lookup recursive
652
    def test__get_matching_sections_subdir_trailing_slash(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
653
        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
654
        self.assertEqual([('/b/', '')],
1993.3.1 by James Henstridge
first go at making location config lookup recursive
655
                         self.my_location_config._get_matching_sections())
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
656
1993.3.1 by James Henstridge
first go at making location config lookup recursive
657
    def test__get_matching_sections_subdir_child(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
658
        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
659
        self.assertEqual([('/a/*', ''), ('/a/', 'foo')],
1993.3.1 by James Henstridge
first go at making location config lookup recursive
660
                         self.my_location_config._get_matching_sections())
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
661
1993.3.1 by James Henstridge
first go at making location config lookup recursive
662
    def test__get_matching_sections_subdir_child_child(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
663
        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
664
        self.assertEqual([('/a/*', 'bar'), ('/a/', 'foo/bar')],
1993.3.1 by James Henstridge
first go at making location config lookup recursive
665
                         self.my_location_config._get_matching_sections())
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
666
1993.3.1 by James Henstridge
first go at making location config lookup recursive
667
    def test__get_matching_sections_trailing_slash_with_children(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
668
        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
669
        self.assertEqual([('/a/', '')],
1993.3.1 by James Henstridge
first go at making location config lookup recursive
670
                         self.my_location_config._get_matching_sections())
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
671
1993.3.1 by James Henstridge
first go at making location config lookup recursive
672
    def test__get_matching_sections_explicit_over_glob(self):
673
        # XXX: 2006-09-08 jamesh
674
        # This test only passes because ord('c') > ord('*').  If there
675
        # was a config section for '/a/?', it would get precedence
676
        # over '/a/c'.
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
677
        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
678
        self.assertEqual([('/a/c', ''), ('/a/*', ''), ('/a/', 'c')],
1993.3.1 by James Henstridge
first go at making location config lookup recursive
679
                         self.my_location_config._get_matching_sections())
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
680
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
681
    def test__get_option_policy_normal(self):
682
        self.get_branch_config('http://www.example.com')
683
        self.assertEqual(
684
            self.my_location_config._get_config_policy(
685
            'http://www.example.com', 'normal_option'),
686
            config.POLICY_NONE)
687
688
    def test__get_option_policy_norecurse(self):
689
        self.get_branch_config('http://www.example.com')
690
        self.assertEqual(
691
            self.my_location_config._get_option_policy(
692
            'http://www.example.com', 'norecurse_option'),
693
            config.POLICY_NORECURSE)
694
        # Test old recurse=False setting:
695
        self.assertEqual(
696
            self.my_location_config._get_option_policy(
697
            'http://www.example.com/norecurse', 'normal_option'),
698
            config.POLICY_NORECURSE)
699
700
    def test__get_option_policy_normal(self):
701
        self.get_branch_config('http://www.example.com')
702
        self.assertEqual(
703
            self.my_location_config._get_option_policy(
704
            'http://www.example.com', 'appendpath_option'),
705
            config.POLICY_APPENDPATH)
706
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
707
    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
708
        self.get_branch_config('http://www.example.com/ignoreparent')
1704.2.18 by Martin Pool
Remove duplicated TestLocationConfig and update previously hidden tests. (#32587)
709
        self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
710
                         self.my_config.username())
711
712
    def test_location_not_listed(self):
1704.2.18 by Martin Pool
Remove duplicated TestLocationConfig and update previously hidden tests. (#32587)
713
        """Test that the global username is used when no location matches"""
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
714
        self.get_branch_config('/home/robertc/sources')
1704.2.18 by Martin Pool
Remove duplicated TestLocationConfig and update previously hidden tests. (#32587)
715
        self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
1442.1.8 by Robert Collins
preparing some tests for LocationConfig
716
                         self.my_config.username())
717
1442.1.13 by Robert Collins
branches.conf is now able to override the users email
718
    def test_overriding_location(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
719
        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
720
        self.assertEqual('Robert Collins <robertc@example.org>',
721
                         self.my_config.username())
1442.1.16 by Robert Collins
allow global overriding of signature policy to never check
722
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
723
    def test_signatures_not_set(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
724
        self.get_branch_config('http://www.example.com',
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
725
                                 global_config=sample_ignore_signatures)
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
726
        self.assertEqual(config.CHECK_ALWAYS,
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
727
                         self.my_config.signature_checking())
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
728
        self.assertEqual(config.SIGN_NEVER,
729
                         self.my_config.signing_policy())
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
730
731
    def test_signatures_never(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
732
        self.get_branch_config('/a/c')
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
733
        self.assertEqual(config.CHECK_NEVER,
734
                         self.my_config.signature_checking())
735
        
1442.1.16 by Robert Collins
allow global overriding of signature policy to never check
736
    def test_signatures_when_available(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
737
        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
738
        self.assertEqual(config.CHECK_IF_POSSIBLE,
739
                         self.my_config.signature_checking())
1442.1.13 by Robert Collins
branches.conf is now able to override the users email
740
        
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
741
    def test_signatures_always(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
742
        self.get_branch_config('/b')
1442.1.18 by Robert Collins
permit per branch location overriding of signature checking policy
743
        self.assertEqual(config.CHECK_ALWAYS,
744
                         self.my_config.signature_checking())
745
        
1442.1.56 by Robert Collins
gpg_signing_command configuration item
746
    def test_gpg_signing_command(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
747
        self.get_branch_config('/b')
1442.1.56 by Robert Collins
gpg_signing_command configuration item
748
        self.assertEqual("gnome-gpg", self.my_config.gpg_signing_command())
749
750
    def test_gpg_signing_command_missing(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
751
        self.get_branch_config('/a')
1442.1.56 by Robert Collins
gpg_signing_command configuration item
752
        self.assertEqual("false", self.my_config.gpg_signing_command())
753
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
754
    def test_get_user_option_global(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
755
        self.get_branch_config('/a')
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
756
        self.assertEqual('something',
757
                         self.my_config.get_user_option('user_global_option'))
758
759
    def test_get_user_option_local(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
760
        self.get_branch_config('/a')
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
761
        self.assertEqual('local',
762
                         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
763
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
764
    def test_get_user_option_appendpath(self):
765
        # returned as is for the base path:
766
        self.get_branch_config('http://www.example.com')
767
        self.assertEqual('append',
768
                         self.my_config.get_user_option('appendpath_option'))
769
        # Extra path components get appended:
770
        self.get_branch_config('http://www.example.com/a/b/c')
771
        self.assertEqual('append/a/b/c',
772
                         self.my_config.get_user_option('appendpath_option'))
773
        # Overriden for http://www.example.com/dir, where it is a
774
        # normal option:
775
        self.get_branch_config('http://www.example.com/dir/a/b/c')
776
        self.assertEqual('normal',
777
                         self.my_config.get_user_option('appendpath_option'))
778
779
    def test_get_user_option_norecurse(self):
780
        self.get_branch_config('http://www.example.com')
781
        self.assertEqual('norecurse',
782
                         self.my_config.get_user_option('norecurse_option'))
783
        self.get_branch_config('http://www.example.com/dir')
784
        self.assertEqual(None,
785
                         self.my_config.get_user_option('norecurse_option'))
786
        # http://www.example.com/norecurse is a recurse=False section
787
        # that redefines normal_option.  Subdirectories do not pick up
788
        # this redefinition.
789
        self.get_branch_config('http://www.example.com/norecurse')
790
        self.assertEqual('norecurse',
791
                         self.my_config.get_user_option('normal_option'))
792
        self.get_branch_config('http://www.example.com/norecurse/subdir')
793
        self.assertEqual('normal',
794
                         self.my_config.get_user_option('normal_option'))
795
2120.6.4 by James Henstridge
add support for specifying policy when storing options
796
    def test_set_user_option_norecurse(self):
797
        self.get_branch_config('http://www.example.com')
798
        self.my_config.set_user_option('foo', 'bar',
799
                                       store=config.STORE_LOCATION_NORECURSE)
800
        self.assertEqual(
801
            self.my_location_config._get_option_policy(
802
            'http://www.example.com', 'foo'),
803
            config.POLICY_NORECURSE)
804
805
    def test_set_user_option_appendpath(self):
806
        self.get_branch_config('http://www.example.com')
807
        self.my_config.set_user_option('foo', 'bar',
808
                                       store=config.STORE_LOCATION_APPENDPATH)
809
        self.assertEqual(
810
            self.my_location_config._get_option_policy(
811
            'http://www.example.com', 'foo'),
812
            config.POLICY_APPENDPATH)
813
814
    def test_set_user_option_change_policy(self):
815
        self.get_branch_config('http://www.example.com')
816
        self.my_config.set_user_option('norecurse_option', 'normal',
817
                                       store=config.STORE_LOCATION)
818
        self.assertEqual(
819
            self.my_location_config._get_option_policy(
820
            'http://www.example.com', 'norecurse_option'),
821
            config.POLICY_NONE)
822
823
    def test_set_user_option_recurse_false_section(self):
2120.6.9 by James Henstridge
Fixes for issues brought up in John's review
824
        # The following section has recurse=False set.  The test is to
825
        # make sure that a normal option can be added to the section,
826
        # converting recurse=False to the norecurse policy.
2120.6.4 by James Henstridge
add support for specifying policy when storing options
827
        self.get_branch_config('http://www.example.com/norecurse')
2120.6.11 by James Henstridge
s/0.13/0.14/ in deprecation warning
828
        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
829
                             'The section "http://www.example.com/norecurse" '
830
                             'has been converted to use policies.'],
831
                            self.my_config.set_user_option,
832
                            'foo', 'bar', store=config.STORE_LOCATION)
2120.6.4 by James Henstridge
add support for specifying policy when storing options
833
        self.assertEqual(
834
            self.my_location_config._get_option_policy(
835
            'http://www.example.com/norecurse', 'foo'),
836
            config.POLICY_NONE)
837
        # The previously existing option is still norecurse:
838
        self.assertEqual(
839
            self.my_location_config._get_option_policy(
840
            'http://www.example.com/norecurse', 'normal_option'),
841
            config.POLICY_NORECURSE)
842
1472 by Robert Collins
post commit hook, first pass implementation
843
    def test_post_commit_default(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
844
        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
845
        self.assertEqual('bzrlib.tests.test_config.post_commit',
1472 by Robert Collins
post commit hook, first pass implementation
846
                         self.my_config.post_commit())
1442.1.69 by Robert Collins
config.Config has a 'get_user_option' call that accepts an option name.
847
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
848
    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.
849
        if global_config is None:
1551.2.20 by Aaron Bentley
Treated config files as utf-8
850
            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.
851
        else:
1551.2.20 by Aaron Bentley
Treated config files as utf-8
852
            global_file = StringIO(global_config.encode('utf-8'))
853
        branches_file = StringIO(sample_branches_text.encode('utf-8'))
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
854
        self.my_config = config.BranchConfig(FakeBranch(location))
855
        # Force location config to use specified file
856
        self.my_location_config = self.my_config._get_location_config()
857
        self.my_location_config._get_parser(branches_file)
858
        # 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.
859
        self.my_config._get_global_config()._get_parser(global_file)
860
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
861
    def test_set_user_setting_sets_and_saves(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
862
        self.get_branch_config('/a/c')
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
863
        record = InstrumentedConfigObj("foo")
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
864
        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
865
866
        real_mkdir = os.mkdir
867
        self.created = False
868
        def checked_mkdir(path, mode=0777):
869
            self.log('making directory: %s', path)
870
            real_mkdir(path, mode)
871
            self.created = True
872
873
        os.mkdir = checked_mkdir
874
        try:
2120.6.10 by James Henstridge
Catch another deprecation warning, and more cleanup
875
            self.callDeprecated(['The recurse option is deprecated as of '
2120.6.11 by James Henstridge
s/0.13/0.14/ in deprecation warning
876
                                 '0.14.  The section "/a/c" has been '
2120.6.10 by James Henstridge
Catch another deprecation warning, and more cleanup
877
                                 'converted to use policies.'],
878
                                self.my_config.set_user_option,
879
                                '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
880
        finally:
881
            os.mkdir = real_mkdir
882
883
        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.
884
        self.assertEqual([('__contains__', '/a/c'),
885
                          ('__contains__', '/a/c/'),
886
                          ('__setitem__', '/a/c', {}),
887
                          ('__getitem__', '/a/c'),
888
                          ('__setitem__', 'foo', 'bar'),
2120.6.4 by James Henstridge
add support for specifying policy when storing options
889
                          ('__getitem__', '/a/c'),
890
                          ('as_bool', 'recurse'),
891
                          ('__getitem__', '/a/c'),
892
                          ('__delitem__', 'recurse'),
893
                          ('__getitem__', '/a/c'),
894
                          ('keys',),
2120.6.8 by James Henstridge
Change syntax for setting config option policies. Rather than
895
                          ('__getitem__', '/a/c'),
896
                          ('__contains__', 'foo:policy'),
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
897
                          ('write',)],
898
                         record._calls[1:])
899
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
900
    def test_set_user_setting_sets_and_saves2(self):
901
        self.get_branch_config('/a/c')
902
        self.assertIs(self.my_config.get_user_option('foo'), None)
903
        self.my_config.set_user_option('foo', 'bar')
904
        self.assertEqual(
905
            self.my_config.branch.control_files.files['branch.conf'], 
906
            'foo = bar')
907
        self.assertEqual(self.my_config.get_user_option('foo'), 'bar')
2120.6.4 by James Henstridge
add support for specifying policy when storing options
908
        self.my_config.set_user_option('foo', 'baz',
909
                                       store=config.STORE_LOCATION)
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
910
        self.assertEqual(self.my_config.get_user_option('foo'), 'baz')
911
        self.my_config.set_user_option('foo', 'qux')
912
        self.assertEqual(self.my_config.get_user_option('foo'), 'baz')
913
        
1551.18.17 by Aaron Bentley
Introduce bzr_remote_path configuration variable
914
    def test_get_bzr_remote_path(self):
915
        my_config = config.LocationConfig('/a/c')
916
        self.assertEqual('bzr', my_config.get_bzr_remote_path())
917
        my_config.set_user_option('bzr_remote_path', '/path-bzr')
918
        self.assertEqual('/path-bzr', my_config.get_bzr_remote_path())
919
        os.environ['BZR_REMOTE_PATH'] = '/environ-bzr'
920
        self.assertEqual('/environ-bzr', my_config.get_bzr_remote_path())
921
1185.62.7 by John Arbash Meinel
Whitespace cleanup.
922
1770.2.8 by Aaron Bentley
Add precedence test
923
precedence_global = 'option = global'
924
precedence_branch = 'option = branch'
925
precedence_location = """
926
[http://]
927
recurse = true
928
option = recurse
929
[http://example.com/specific]
930
option = exact
931
"""
932
933
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
934
class TestBranchConfigItems(tests.TestCaseInTempDir):
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
935
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
936
    def get_branch_config(self, global_config=None, location=None, 
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
937
                          location_config=None, branch_data_config=None):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
938
        my_config = config.BranchConfig(FakeBranch(location))
939
        if global_config is not None:
940
            global_file = StringIO(global_config.encode('utf-8'))
941
            my_config._get_global_config()._get_parser(global_file)
942
        self.my_location_config = my_config._get_location_config()
943
        if location_config is not None:
944
            location_file = StringIO(location_config.encode('utf-8'))
945
            self.my_location_config._get_parser(location_file)
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
946
        if branch_data_config is not None:
947
            my_config.branch.control_files.files['branch.conf'] = \
948
                branch_data_config
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
949
        return my_config
950
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
951
    def test_user_id(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
952
        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
953
        my_config = config.BranchConfig(branch)
954
        self.assertEqual("Robert Collins <robertc@example.net>",
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
955
                         my_config.username())
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
956
        branch.control_files.email = "John"
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
957
        my_config.set_user_option('email', 
958
                                  "Robert Collins <robertc@example.org>")
959
        self.assertEqual("John", my_config.username())
960
        branch.control_files.email = None
961
        self.assertEqual("Robert Collins <robertc@example.org>",
962
                         my_config.username())
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
963
964
    def test_not_set_in_branch(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
965
        my_config = self.get_branch_config(sample_config_text)
966
        my_config.branch.control_files.email = None
1551.2.21 by Aaron Bentley
Formatted unicode config tests as ASCII
967
        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
968
                         my_config._get_user_id())
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
969
        my_config.branch.control_files.email = "John"
1442.1.6 by Robert Collins
first stage major overhaul of configs, giving use BranchConfigs, LocationConfigs and GlobalConfigs
970
        self.assertEqual("John", my_config._get_user_id())
971
1861.4.1 by Matthieu Moy
BZREMAIL renamed to BZR_EMAIL.
972
    def test_BZR_EMAIL_OVERRIDES(self):
973
        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
974
        branch = FakeBranch()
975
        my_config = config.BranchConfig(branch)
976
        self.assertEqual("Robert Collins <robertc@example.org>",
977
                         my_config.username())
978
    
1442.1.19 by Robert Collins
BranchConfigs inherit signature_checking policy from their LocationConfig.
979
    def test_signatures_forced(self):
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
980
        my_config = self.get_branch_config(
981
            global_config=sample_always_signatures)
1770.2.1 by Aaron Bentley
Use create_signature for signing policy, deprecate check_signatures for this
982
        self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
983
        self.assertEqual(config.SIGN_ALWAYS, my_config.signing_policy())
984
        self.assertTrue(my_config.signature_needed())
1442.1.56 by Robert Collins
gpg_signing_command configuration item
985
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
986
    def test_signatures_forced_branch(self):
987
        my_config = self.get_branch_config(
988
            global_config=sample_ignore_signatures,
989
            branch_data_config=sample_always_signatures)
990
        self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
991
        self.assertEqual(config.SIGN_ALWAYS, my_config.signing_policy())
992
        self.assertTrue(my_config.signature_needed())
993
1442.1.56 by Robert Collins
gpg_signing_command configuration item
994
    def test_gpg_signing_command(self):
1770.2.10 by Aaron Bentley
Added test that branch_config can't influence gpg_signing_command
995
        my_config = self.get_branch_config(
996
            # branch data cannot set gpg_signing_command
997
            branch_data_config="gpg_signing_command=pgp")
1551.2.20 by Aaron Bentley
Treated config files as utf-8
998
        config_file = StringIO(sample_config_text.encode('utf-8'))
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
999
        my_config._get_global_config()._get_parser(config_file)
1442.1.56 by Robert Collins
gpg_signing_command configuration item
1000
        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.
1001
1002
    def test_get_user_option_global(self):
1003
        branch = FakeBranch()
1004
        my_config = config.BranchConfig(branch)
1551.2.20 by Aaron Bentley
Treated config files as utf-8
1005
        config_file = StringIO(sample_config_text.encode('utf-8'))
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
1006
        (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.
1007
        self.assertEqual('something',
1008
                         my_config.get_user_option('user_global_option'))
1472 by Robert Collins
post commit hook, first pass implementation
1009
1010
    def test_post_commit_default(self):
1011
        branch = FakeBranch()
1770.2.5 by Aaron Bentley
Integrate branch.conf into BranchConfig
1012
        my_config = self.get_branch_config(sample_config_text, '/a/c',
1013
                                           sample_branches_text)
1014
        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
1015
        self.assertEqual('bzrlib.tests.test_config.post_commit',
1472 by Robert Collins
post commit hook, first pass implementation
1016
                         my_config.post_commit())
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
1017
        my_config.set_user_option('post_commit', 'rmtree_root')
1018
        # post-commit is ignored when bresent in branch data
1019
        self.assertEqual('bzrlib.tests.test_config.post_commit',
1020
                         my_config.post_commit())
2120.6.4 by James Henstridge
add support for specifying policy when storing options
1021
        my_config.set_user_option('post_commit', 'rmtree_root',
1022
                                  store=config.STORE_LOCATION)
1770.2.6 by Aaron Bentley
Ensure branch.conf works properly
1023
        self.assertEqual('rmtree_root', my_config.post_commit())
1185.33.31 by Martin Pool
Make annotate cope better with revisions committed without a valid
1024
1770.2.8 by Aaron Bentley
Add precedence test
1025
    def test_config_precedence(self):
1026
        my_config = self.get_branch_config(global_config=precedence_global)
1027
        self.assertEqual(my_config.get_user_option('option'), 'global')
1028
        my_config = self.get_branch_config(global_config=precedence_global, 
1029
                                      branch_data_config=precedence_branch)
1030
        self.assertEqual(my_config.get_user_option('option'), 'branch')
1031
        my_config = self.get_branch_config(global_config=precedence_global, 
1032
                                      branch_data_config=precedence_branch,
1033
                                      location_config=precedence_location)
1034
        self.assertEqual(my_config.get_user_option('option'), 'recurse')
1035
        my_config = self.get_branch_config(global_config=precedence_global, 
1036
                                      branch_data_config=precedence_branch,
1037
                                      location_config=precedence_location,
1038
                                      location='http://example.com/specific')
1039
        self.assertEqual(my_config.get_user_option('option'), 'exact')
1040
2681.1.8 by Aaron Bentley
Add Thunderbird support to bzr send
1041
    def test_get_mail_client(self):
1042
        config = self.get_branch_config()
1043
        client = config.get_mail_client()
2681.1.24 by Aaron Bentley
Handle default mail client by trying xdg-email, falling back to editor
1044
        self.assertIsInstance(client, mail_client.DefaultMail)
1045
2790.2.2 by Keir Mierle
Change alphabetic ordering into two categories; one for specific clients the other for generic options.
1046
        # Specific clients
2681.1.21 by Aaron Bentley
Refactor prompt generation to make it testable, test it with unicode
1047
        config.set_user_option('mail_client', 'evolution')
1048
        client = config.get_mail_client()
1049
        self.assertIsInstance(client, mail_client.Evolution)
1050
2681.5.1 by ghigo
Add KMail support to bzr send
1051
        config.set_user_option('mail_client', 'kmail')
1052
        client = config.get_mail_client()
1053
        self.assertIsInstance(client, mail_client.KMail)
1054
2790.2.1 by Keir Mierle
Add Mutt as a supported client email program. Also rearranges various listings
1055
        config.set_user_option('mail_client', 'mutt')
1056
        client = config.get_mail_client()
1057
        self.assertIsInstance(client, mail_client.Mutt)
1058
1059
        config.set_user_option('mail_client', 'thunderbird')
1060
        client = config.get_mail_client()
1061
        self.assertIsInstance(client, mail_client.Thunderbird)
1062
2790.2.2 by Keir Mierle
Change alphabetic ordering into two categories; one for specific clients the other for generic options.
1063
        # Generic options
1064
        config.set_user_option('mail_client', 'default')
1065
        client = config.get_mail_client()
1066
        self.assertIsInstance(client, mail_client.DefaultMail)
1067
1068
        config.set_user_option('mail_client', 'editor')
1069
        client = config.get_mail_client()
1070
        self.assertIsInstance(client, mail_client.Editor)
1071
1072
        config.set_user_option('mail_client', 'mapi')
1073
        client = config.get_mail_client()
1074
        self.assertIsInstance(client, mail_client.MAPIClient)
1075
2681.1.23 by Aaron Bentley
Add support for xdg-email
1076
        config.set_user_option('mail_client', 'xdg-email')
1077
        client = config.get_mail_client()
1078
        self.assertIsInstance(client, mail_client.XDGEmail)
1079
2681.1.10 by Aaron Bentley
Clean up handling of unknown mail clients
1080
        config.set_user_option('mail_client', 'firebird')
1081
        self.assertRaises(errors.UnknownMailClient, config.get_mail_client)
1082
1185.33.31 by Martin Pool
Make annotate cope better with revisions committed without a valid
1083
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
1084
class TestMailAddressExtraction(tests.TestCase):
1185.33.31 by Martin Pool
Make annotate cope better with revisions committed without a valid
1085
1086
    def test_extract_email_address(self):
1087
        self.assertEqual('jane@test.com',
1088
                         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
1089
        self.assertRaises(errors.NoEmailInUsername,
1185.33.31 by Martin Pool
Make annotate cope better with revisions committed without a valid
1090
                          config.extract_email_address, 'Jane Tester')
2533.1.1 by James Westby
Fix TreeConfig to return values from sections.
1091
2562.1.2 by John Arbash Meinel
Clean up whitespace
1092
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
1093
class TestTreeConfig(tests.TestCaseWithTransport):
2533.1.1 by James Westby
Fix TreeConfig to return values from sections.
1094
1095
    def test_get_value(self):
1096
        """Test that retreiving a value from a section is possible"""
1097
        branch = self.make_branch('.')
1098
        tree_config = config.TreeConfig(branch)
1099
        tree_config.set_option('value', 'key', 'SECTION')
1100
        tree_config.set_option('value2', 'key2')
1101
        tree_config.set_option('value3-top', 'key3')
1102
        tree_config.set_option('value3-section', 'key3', 'SECTION')
1103
        value = tree_config.get_option('key', 'SECTION')
1104
        self.assertEqual(value, 'value')
1105
        value = tree_config.get_option('key2')
1106
        self.assertEqual(value, 'value2')
1107
        self.assertEqual(tree_config.get_option('non-existant'), None)
1108
        value = tree_config.get_option('non-existant', 'SECTION')
1109
        self.assertEqual(value, None)
1110
        value = tree_config.get_option('non-existant', default='default')
1111
        self.assertEqual(value, 'default')
1112
        self.assertEqual(tree_config.get_option('key2', 'NOSECTION'), None)
1113
        value = tree_config.get_option('key2', 'NOSECTION', default='default')
1114
        self.assertEqual(value, 'default')
1115
        value = tree_config.get_option('key3')
1116
        self.assertEqual(value, 'value3-top')
1117
        value = tree_config.get_option('key3', 'SECTION')
1118
        self.assertEqual(value, 'value3-section')
2900.2.3 by Vincent Ladeuil
Credentials matching implementation.
1119
1120
2900.2.5 by Vincent Ladeuil
ake ftp aware of authentication config.
1121
class TestAuthenticationConfigFile(tests.TestCase):
2900.2.14 by Vincent Ladeuil
More tests.
1122
    """Test the authentication.conf file matching"""
2900.2.3 by Vincent Ladeuil
Credentials matching implementation.
1123
1124
    def _got_user_passwd(self, expected_user, expected_password,
1125
                         config, *args, **kwargs):
1126
        credentials = config.get_credentials(*args, **kwargs)
1127
        if credentials is None:
1128
            user = None
1129
            password = None
1130
        else:
1131
            user = credentials['user']
1132
            password = credentials['password']
1133
        self.assertEquals(expected_user, user)
1134
        self.assertEquals(expected_password, password)
1135
2978.5.1 by John Arbash Meinel
Fix bug #162494, 'bzr register-branch' needs proper auth handling.
1136
    def test_empty_config(self):
2900.2.3 by Vincent Ladeuil
Credentials matching implementation.
1137
        conf = config.AuthenticationConfig(_file=StringIO())
1138
        self.assertEquals({}, conf._get_config())
1139
        self._got_user_passwd(None, None, conf, 'http', 'foo.net')
1140
1141
    def test_broken_config(self):
1142
        conf = config.AuthenticationConfig(_file=StringIO('[DEF'))
1143
        self.assertRaises(errors.ParseConfigError, conf._get_config)
2900.2.15 by Vincent Ladeuil
AuthenticationConfig can be queried for logins too (first step).
1144
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
1145
        conf = config.AuthenticationConfig(_file=StringIO(
1146
                """[broken]
1147
scheme=ftp
1148
user=joe
2900.2.15 by Vincent Ladeuil
AuthenticationConfig can be queried for logins too (first step).
1149
verify_certificates=askme # Error: Not a boolean
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
1150
"""))
1151
        self.assertRaises(ValueError, conf.get_credentials, 'ftp', 'foo.net')
2900.2.22 by Vincent Ladeuil
Polishing.
1152
        conf = config.AuthenticationConfig(_file=StringIO(
1153
                """[broken]
1154
scheme=ftp
1155
user=joe
1156
port=port # Error: Not an int
1157
"""))
1158
        self.assertRaises(ValueError, conf.get_credentials, 'ftp', 'foo.net')
2900.2.3 by Vincent Ladeuil
Credentials matching implementation.
1159
1160
    def test_credentials_for_scheme_host(self):
1161
        conf = config.AuthenticationConfig(_file=StringIO(
1162
                """# Identity on foo.net
1163
[ftp definition]
1164
scheme=ftp
1165
host=foo.net
1166
user=joe
1167
password=secret-pass
1168
"""))
1169
        # Basic matching
1170
        self._got_user_passwd('joe', 'secret-pass', conf, 'ftp', 'foo.net')
1171
        # different scheme
1172
        self._got_user_passwd(None, None, conf, 'http', 'foo.net')
1173
        # different host
1174
        self._got_user_passwd(None, None, conf, 'ftp', 'bar.net')
1175
1176
    def test_credentials_for_host_port(self):
1177
        conf = config.AuthenticationConfig(_file=StringIO(
1178
                """# Identity on foo.net
1179
[ftp definition]
1180
scheme=ftp
1181
port=10021
1182
host=foo.net
1183
user=joe
1184
password=secret-pass
1185
"""))
1186
        # No port
1187
        self._got_user_passwd('joe', 'secret-pass',
1188
                              conf, 'ftp', 'foo.net', port=10021)
1189
        # different port
1190
        self._got_user_passwd(None, None, conf, 'ftp', 'foo.net')
1191
1192
    def test_for_matching_host(self):
1193
        conf = config.AuthenticationConfig(_file=StringIO(
1194
                """# Identity on foo.net
1195
[sourceforge]
1196
scheme=bzr
1197
host=bzr.sf.net
1198
user=joe
1199
password=joepass
1200
[sourceforge domain]
1201
scheme=bzr
1202
host=.bzr.sf.net
1203
user=georges
1204
password=bendover
1205
"""))
1206
        # matching domain
1207
        self._got_user_passwd('georges', 'bendover',
1208
                              conf, 'bzr', 'foo.bzr.sf.net')
1209
        # phishing attempt
1210
        self._got_user_passwd(None, None,
1211
                              conf, 'bzr', 'bbzr.sf.net')
1212
1213
    def test_for_matching_host_None(self):
1214
        conf = config.AuthenticationConfig(_file=StringIO(
1215
                """# Identity on foo.net
1216
[catchup bzr]
1217
scheme=bzr
1218
user=joe
1219
password=joepass
1220
[DEFAULT]
1221
user=georges
1222
password=bendover
1223
"""))
1224
        # match no host
1225
        self._got_user_passwd('joe', 'joepass',
1226
                              conf, 'bzr', 'quux.net')
1227
        # no host but different scheme
1228
        self._got_user_passwd('georges', 'bendover',
1229
                              conf, 'ftp', 'quux.net')
1230
1231
    def test_credentials_for_path(self):
1232
        conf = config.AuthenticationConfig(_file=StringIO(
1233
                """
1234
[http dir1]
1235
scheme=http
1236
host=bar.org
1237
path=/dir1
1238
user=jim
1239
password=jimpass
1240
[http dir2]
1241
scheme=http
1242
host=bar.org
1243
path=/dir2
1244
user=georges
1245
password=bendover
1246
"""))
1247
        # no path no dice
1248
        self._got_user_passwd(None, None,
1249
                              conf, 'http', host='bar.org', path='/dir3')
1250
        # matching path
1251
        self._got_user_passwd('georges', 'bendover',
1252
                              conf, 'http', host='bar.org', path='/dir2')
1253
        # matching subdir
1254
        self._got_user_passwd('jim', 'jimpass',
1255
                              conf, 'http', host='bar.org',path='/dir1/subdir')
1256
1257
    def test_credentials_for_user(self):
1258
        conf = config.AuthenticationConfig(_file=StringIO(
1259
                """
1260
[with user]
1261
scheme=http
1262
host=bar.org
1263
user=jim
1264
password=jimpass
1265
"""))
1266
        # Get user
1267
        self._got_user_passwd('jim', 'jimpass',
1268
                              conf, 'http', 'bar.org')
1269
        # Get same user
1270
        self._got_user_passwd('jim', 'jimpass',
1271
                              conf, 'http', 'bar.org', user='jim')
1272
        # Don't get a different user if one is specified
1273
        self._got_user_passwd(None, None,
1274
                              conf, 'http', 'bar.org', user='georges')
1275
1276
    def test_verify_certificates(self):
1277
        conf = config.AuthenticationConfig(_file=StringIO(
1278
                """
1279
[self-signed]
1280
scheme=https
1281
host=bar.org
1282
user=jim
1283
password=jimpass
1284
verify_certificates=False
1285
[normal]
1286
scheme=https
1287
host=foo.net
1288
user=georges
1289
password=bendover
1290
"""))
1291
        credentials = conf.get_credentials('https', 'bar.org')
1292
        self.assertEquals(False, credentials.get('verify_certificates'))
1293
        credentials = conf.get_credentials('https', 'foo.net')
1294
        self.assertEquals(True, credentials.get('verify_certificates'))
2900.2.4 by Vincent Ladeuil
Cosmetic changes.
1295
2900.2.5 by Vincent Ladeuil
ake ftp aware of authentication config.
1296
2900.2.14 by Vincent Ladeuil
More tests.
1297
class TestAuthenticationConfig(tests.TestCase):
1298
    """Test AuthenticationConfig behaviour"""
1299
1300
    def _check_default_prompt(self, expected_prompt_format, scheme,
1301
                              host=None, port=None, realm=None, path=None):
1302
        if host is None:
1303
            host = 'bar.org'
1304
        user, password = 'jim', 'precious'
1305
        expected_prompt = expected_prompt_format % {
1306
            'scheme': scheme, 'host': host, 'port': port,
1307
            'user': user, 'realm': realm}
1308
1309
        stdout = tests.StringIOWrapper()
1310
        ui.ui_factory = tests.TestUIFactory(stdin=password + '\n',
1311
                                            stdout=stdout)
1312
        # We use an empty conf so that the user is always prompted
1313
        conf = config.AuthenticationConfig()
1314
        self.assertEquals(password,
1315
                          conf.get_password(scheme, host, user, port=port,
1316
                                            realm=realm, path=path))
1317
        self.assertEquals(stdout.getvalue(), expected_prompt)
1318
1319
    def test_default_prompts(self):
2900.2.19 by Vincent Ladeuil
Mention proxy and https in the password prompts, with tests.
1320
        # HTTP prompts can't be tested here, see test_http.py
2900.2.14 by Vincent Ladeuil
More tests.
1321
        self._check_default_prompt('FTP %(user)s@%(host)s password: ', 'ftp')
1322
        self._check_default_prompt('FTP %(user)s@%(host)s:%(port)d password: ',
1323
                                   'ftp', port=10020)
1324
1325
        self._check_default_prompt('SSH %(user)s@%(host)s:%(port)d password: ',
1326
                                   'ssh', port=12345)
1327
        # SMTP port handling is a bit special (it's handled if embedded in the
1328
        # host too)
2900.2.22 by Vincent Ladeuil
Polishing.
1329
        # FIXME: should we: forbid that, extend it to other schemes, leave
1330
        # things as they are that's fine thank you ?
2900.2.14 by Vincent Ladeuil
More tests.
1331
        self._check_default_prompt('SMTP %(user)s@%(host)s password: ',
1332
                                   'smtp')
1333
        self._check_default_prompt('SMTP %(user)s@%(host)s password: ',
1334
                                   'smtp', host='bar.org:10025')
1335
        self._check_default_prompt(
1336
            'SMTP %(user)s@%(host)s:%(port)d password: ',
1337
            'smtp', port=10025)
1338
1339
1340
# 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.
1341
# can implement generic tests.
2900.2.15 by Vincent Ladeuil
AuthenticationConfig can be queried for logins too (first step).
1342
# test_user_password_in_url
1343
# test_user_in_url_password_from_config
1344
# test_user_in_url_password_prompted
1345
# test_user_in_config
1346
# test_user_getpass.getuser
1347
# test_user_prompted ?
2900.2.5 by Vincent Ladeuil
ake ftp aware of authentication config.
1348
class TestAuthenticationRing(tests.TestCaseWithTransport):
1349
    pass