~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/testconfig.py

  • Committer: Robert Collins
  • Date: 2005-10-11 07:00:25 UTC
  • mto: This revision was merged to the branch mainline in revision 1443.
  • Revision ID: robertc@robertcollins.net-20051011070025-bac6b53cb6186dfd
create a config module - there is enough config logic to make this worthwhile, and start testing config processing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 by Canonical Ltd
 
1
# Copyright (C) 2005 by Canonical Ltd
2
2
#   Authors: Robert Collins <robert.collins@canonical.com>
3
3
#
4
4
# This program is free software; you can redistribute it and/or modify
17
17
 
18
18
"""Tests for finding and reading the bzr config file[s]."""
19
19
# import system imports here
20
 
from bzrlib.util.configobj.configobj import ConfigObj, ConfigObjError
 
20
from ConfigParser import ConfigParser
21
21
from cStringIO import StringIO
22
22
import os
23
23
import sys
24
24
 
25
25
#import bzrlib specific imports here
26
 
from bzrlib import (
27
 
    config,
28
 
    errors,
29
 
    osutils,
30
 
    urlutils,
31
 
    )
32
 
from bzrlib.branch import Branch
33
 
from bzrlib.bzrdir import BzrDir
34
 
from bzrlib.tests import TestCase, TestCaseInTempDir, TestCaseWithTransport
35
 
 
36
 
 
37
 
sample_long_alias="log -r-15..-1 --line"
 
26
import bzrlib.config as config
 
27
from bzrlib.selftest import TestCase, TestCaseInTempDir
 
28
 
 
29
 
38
30
sample_config_text = ("[DEFAULT]\n"
39
 
                      u"email=Erik B\u00e5gfors <erik@bagfors.nu>\n"
 
31
                      "email=Robert Collins <robertc@example.com>\n"
40
32
                      "editor=vim\n"
41
 
                      "gpg_signing_command=gnome-gpg\n"
42
 
                      "log_format=short\n"
43
 
                      "user_global_option=something\n"
44
 
                      "[ALIASES]\n"
45
 
                      "h=help\n"
46
 
                      "ll=" + sample_long_alias + "\n")
47
 
 
48
 
 
49
 
sample_always_signatures = ("[DEFAULT]\n"
50
 
                            "check_signatures=ignore\n"
51
 
                            "create_signatures=always")
52
 
 
53
 
 
54
 
sample_ignore_signatures = ("[DEFAULT]\n"
55
 
                            "check_signatures=require\n"
56
 
                            "create_signatures=never")
57
 
 
58
 
 
59
 
sample_maybe_signatures = ("[DEFAULT]\n"
60
 
                            "check_signatures=ignore\n"
61
 
                            "create_signatures=when-required")
62
 
 
63
 
 
64
 
sample_branches_text = ("[http://www.example.com]\n"
65
 
                        "# Top level policy\n"
66
 
                        "email=Robert Collins <robertc@example.org>\n"
67
 
                        "[http://www.example.com/useglobal]\n"
68
 
                        "# different project, forces global lookup\n"
69
 
                        "recurse=false\n"
70
 
                        "[/b/]\n"
71
 
                        "check_signatures=require\n"
72
 
                        "# test trailing / matching with no children\n"
73
 
                        "[/a/]\n"
74
 
                        "check_signatures=check-available\n"
75
 
                        "gpg_signing_command=false\n"
76
 
                        "user_local_option=local\n"
77
 
                        "# test trailing / matching\n"
78
 
                        "[/a/*]\n"
79
 
                        "#subdirs will match but not the parent\n"
80
 
                        "recurse=False\n"
81
 
                        "[/a/c]\n"
82
 
                        "check_signatures=ignore\n"
83
 
                        "post_commit=bzrlib.tests.test_config.post_commit\n"
84
 
                        "#testing explicit beats globs\n")
85
 
 
86
 
 
87
 
 
88
 
class InstrumentedConfigObj(object):
89
 
    """A config obj look-enough-alike to record calls made to it."""
90
 
 
91
 
    def __contains__(self, thing):
92
 
        self._calls.append(('__contains__', thing))
93
 
        return False
94
 
 
95
 
    def __getitem__(self, key):
96
 
        self._calls.append(('__getitem__', key))
97
 
        return self
98
 
 
99
 
    def __init__(self, input, encoding=None):
100
 
        self._calls = [('__init__', input, encoding)]
101
 
 
102
 
    def __setitem__(self, key, value):
103
 
        self._calls.append(('__setitem__', key, value))
104
 
 
105
 
    def write(self, arg):
106
 
        self._calls.append(('write',))
107
 
 
108
 
 
109
 
class FakeBranch(object):
110
 
 
111
 
    def __init__(self, base=None, user_id=None):
112
 
        if base is None:
113
 
            self.base = "http://example.com/branches/demo"
114
 
        else:
115
 
            self.base = base
116
 
        self.control_files = FakeControlFiles(user_id=user_id)
117
 
 
118
 
    def lock_write(self):
119
 
        pass
120
 
 
121
 
    def unlock(self):
122
 
        pass
123
 
 
124
 
 
125
 
class FakeControlFiles(object):
126
 
 
127
 
    def __init__(self, user_id=None):
128
 
        self.email = user_id
129
 
        self.files = {}
130
 
 
131
 
    def get_utf8(self, filename):
132
 
        if filename != 'email':
133
 
            raise NotImplementedError
134
 
        if self.email is not None:
135
 
            return StringIO(self.email)
136
 
        raise errors.NoSuchFile(filename)
137
 
 
138
 
    def get(self, filename):
139
 
        try:
140
 
            return StringIO(self.files[filename])
141
 
        except KeyError:
142
 
            raise errors.NoSuchFile(filename)
143
 
 
144
 
    def put(self, filename, fileobj):
145
 
        self.files[filename] = fileobj.read()
146
 
 
147
 
 
148
 
class InstrumentedConfig(config.Config):
149
 
    """An instrumented config that supplies stubs for template methods."""
150
 
    
 
33
                      "gpg_signing_command=gnome-gpg\n")
 
34
 
 
35
class InstrumentedConfigParser(object):
 
36
    """A config parser look-enough-alike to record calls made to it."""
 
37
 
151
38
    def __init__(self):
152
 
        super(InstrumentedConfig, self).__init__()
153
39
        self._calls = []
154
 
        self._signatures = config.CHECK_NEVER
155
 
 
156
 
    def _get_user_id(self):
157
 
        self._calls.append('_get_user_id')
158
 
        return "Robert Collins <robert.collins@example.org>"
159
 
 
160
 
    def _get_signature_checking(self):
161
 
        self._calls.append('_get_signature_checking')
162
 
        return self._signatures
163
 
 
164
 
 
165
 
bool_config = """[DEFAULT]
166
 
active = true
167
 
inactive = false
168
 
[UPPERCASE]
169
 
active = True
170
 
nonactive = False
171
 
"""
172
 
class TestConfigObj(TestCase):
173
 
    def test_get_bool(self):
174
 
        from bzrlib.config import ConfigObj
175
 
        co = ConfigObj(StringIO(bool_config))
176
 
        self.assertIs(co.get_bool('DEFAULT', 'active'), True)
177
 
        self.assertIs(co.get_bool('DEFAULT', 'inactive'), False)
178
 
        self.assertIs(co.get_bool('UPPERCASE', 'active'), True)
179
 
        self.assertIs(co.get_bool('UPPERCASE', 'nonactive'), False)
180
 
 
181
 
 
182
 
class TestConfig(TestCase):
183
 
 
184
 
    def test_constructs(self):
185
 
        config.Config()
186
 
 
187
 
    def test_no_default_editor(self):
188
 
        self.assertRaises(NotImplementedError, config.Config().get_editor)
189
 
 
190
 
    def test_user_email(self):
191
 
        my_config = InstrumentedConfig()
192
 
        self.assertEqual('robert.collins@example.org', my_config.user_email())
193
 
        self.assertEqual(['_get_user_id'], my_config._calls)
194
 
 
195
 
    def test_username(self):
196
 
        my_config = InstrumentedConfig()
197
 
        self.assertEqual('Robert Collins <robert.collins@example.org>',
198
 
                         my_config.username())
199
 
        self.assertEqual(['_get_user_id'], my_config._calls)
200
 
 
201
 
    def test_signatures_default(self):
202
 
        my_config = config.Config()
203
 
        self.assertFalse(my_config.signature_needed())
204
 
        self.assertEqual(config.CHECK_IF_POSSIBLE,
205
 
                         my_config.signature_checking())
206
 
        self.assertEqual(config.SIGN_WHEN_REQUIRED,
207
 
                         my_config.signing_policy())
208
 
 
209
 
    def test_signatures_template_method(self):
210
 
        my_config = InstrumentedConfig()
211
 
        self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
212
 
        self.assertEqual(['_get_signature_checking'], my_config._calls)
213
 
 
214
 
    def test_signatures_template_method_none(self):
215
 
        my_config = InstrumentedConfig()
216
 
        my_config._signatures = None
217
 
        self.assertEqual(config.CHECK_IF_POSSIBLE,
218
 
                         my_config.signature_checking())
219
 
        self.assertEqual(['_get_signature_checking'], my_config._calls)
220
 
 
221
 
    def test_gpg_signing_command_default(self):
222
 
        my_config = config.Config()
223
 
        self.assertEqual('gpg', my_config.gpg_signing_command())
224
 
 
225
 
    def test_get_user_option_default(self):
226
 
        my_config = config.Config()
227
 
        self.assertEqual(None, my_config.get_user_option('no_option'))
228
 
 
229
 
    def test_post_commit_default(self):
230
 
        my_config = config.Config()
231
 
        self.assertEqual(None, my_config.post_commit())
232
 
 
233
 
    def test_log_format_default(self):
234
 
        my_config = config.Config()
235
 
        self.assertEqual('long', my_config.log_format())
 
40
 
 
41
    def read(self, filenames):
 
42
        self._calls.append(('read', filenames))
236
43
 
237
44
 
238
45
class TestConfigPath(TestCase):
239
46
 
240
47
    def setUp(self):
241
48
        super(TestConfigPath, self).setUp()
242
 
        self.old_home = os.environ.get('HOME', None)
243
 
        self.old_appdata = os.environ.get('APPDATA', None)
 
49
        self.oldenv = os.environ.get('HOME', None)
244
50
        os.environ['HOME'] = '/home/bogus'
245
 
        os.environ['APPDATA'] = \
246
 
            r'C:\Documents and Settings\bogus\Application Data'
247
51
 
248
52
    def tearDown(self):
249
 
        if self.old_home is None:
250
 
            del os.environ['HOME']
251
 
        else:
252
 
            os.environ['HOME'] = self.old_home
253
 
        if self.old_appdata is None:
254
 
            del os.environ['APPDATA']
255
 
        else:
256
 
            os.environ['APPDATA'] = self.old_appdata
257
 
        super(TestConfigPath, self).tearDown()
 
53
        os.environ['HOME'] = self.oldenv
258
54
    
259
55
    def test_config_dir(self):
260
 
        if sys.platform == 'win32':
261
 
            self.assertEqual(config.config_dir(), 
262
 
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0')
263
 
        else:
264
 
            self.assertEqual(config.config_dir(), '/home/bogus/.bazaar')
 
56
        self.assertEqual(config.config_dir(), '/home/bogus/.bazaar')
265
57
 
266
58
    def test_config_filename(self):
267
 
        if sys.platform == 'win32':
268
 
            self.assertEqual(config.config_filename(), 
269
 
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0/bazaar.conf')
270
 
        else:
271
 
            self.assertEqual(config.config_filename(),
272
 
                             '/home/bogus/.bazaar/bazaar.conf')
273
 
 
274
 
    def test_branches_config_filename(self):
275
 
        if sys.platform == 'win32':
276
 
            self.assertEqual(config.branches_config_filename(), 
277
 
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0/branches.conf')
278
 
        else:
279
 
            self.assertEqual(config.branches_config_filename(),
280
 
                             '/home/bogus/.bazaar/branches.conf')
281
 
 
282
 
    def test_locations_config_filename(self):
283
 
        if sys.platform == 'win32':
284
 
            self.assertEqual(config.locations_config_filename(), 
285
 
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0/locations.conf')
286
 
        else:
287
 
            self.assertEqual(config.locations_config_filename(),
288
 
                             '/home/bogus/.bazaar/locations.conf')
289
 
 
290
 
class TestIniConfig(TestCase):
291
 
 
292
 
    def test_contructs(self):
293
 
        my_config = config.IniBasedConfig("nothing")
 
59
        self.assertEqual(config.config_filename(),
 
60
                         '/home/bogus/.bazaar/bazaar.conf')
 
61
 
 
62
 
 
63
class TestGetConfig(TestCase):
294
64
 
295
65
    def test_from_fp(self):
296
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
297
 
        my_config = config.IniBasedConfig(None)
298
 
        self.failUnless(
299
 
            isinstance(my_config._get_parser(file=config_file),
300
 
                        ConfigObj))
301
 
 
302
 
    def test_cached(self):
303
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
304
 
        my_config = config.IniBasedConfig(None)
305
 
        parser = my_config._get_parser(file=config_file)
306
 
        self.failUnless(my_config._get_parser() is parser)
307
 
 
308
 
 
309
 
class TestGetConfig(TestCase):
310
 
 
311
 
    def test_constructs(self):
312
 
        my_config = config.GlobalConfig()
 
66
        config_file = StringIO(sample_config_text)
 
67
        self.failUnless(isinstance(config._get_config_parser(file=config_file),
 
68
                        ConfigParser))
313
69
 
314
70
    def test_calls_read_filenames(self):
315
 
        # replace the class that is constructured, to check its parameters
316
 
        oldparserclass = config.ConfigObj
317
 
        config.ConfigObj = InstrumentedConfigObj
318
 
        my_config = config.GlobalConfig()
 
71
        # note the monkey patching. if config access was via a class instance,
 
72
        # we would not have to - if this changes in future, be sure to stop 
 
73
        # monkey patching RBC 20051011
 
74
        oldparserclass = config.ConfigParser
 
75
        config.ConfigParser = InstrumentedConfigParser
319
76
        try:
320
 
            parser = my_config._get_parser()
 
77
            parser = config._get_config_parser()
321
78
        finally:
322
 
            config.ConfigObj = oldparserclass
323
 
        self.failUnless(isinstance(parser, InstrumentedConfigObj))
324
 
        self.assertEqual(parser._calls, [('__init__', config.config_filename(),
325
 
                                          'utf-8')])
326
 
 
327
 
 
328
 
class TestBranchConfig(TestCaseWithTransport):
329
 
 
330
 
    def test_constructs(self):
331
 
        branch = FakeBranch()
332
 
        my_config = config.BranchConfig(branch)
333
 
        self.assertRaises(TypeError, config.BranchConfig)
334
 
 
335
 
    def test_get_location_config(self):
336
 
        branch = FakeBranch()
337
 
        my_config = config.BranchConfig(branch)
338
 
        location_config = my_config._get_location_config()
339
 
        self.assertEqual(branch.base, location_config.location)
340
 
        self.failUnless(location_config is my_config._get_location_config())
341
 
 
342
 
    def test_get_config(self):
343
 
        """The Branch.get_config method works properly"""
344
 
        b = BzrDir.create_standalone_workingtree('.').branch
345
 
        my_config = b.get_config()
346
 
        self.assertIs(my_config.get_user_option('wacky'), None)
347
 
        my_config.set_user_option('wacky', 'unlikely')
348
 
        self.assertEqual(my_config.get_user_option('wacky'), 'unlikely')
349
 
 
350
 
        # Ensure we get the same thing if we start again
351
 
        b2 = Branch.open('.')
352
 
        my_config2 = b2.get_config()
353
 
        self.assertEqual(my_config2.get_user_option('wacky'), 'unlikely')
354
 
 
355
 
    def test_has_explicit_nickname(self):
356
 
        b = self.make_branch('.')
357
 
        self.assertFalse(b.get_config().has_explicit_nickname())
358
 
        b.nick = 'foo'
359
 
        self.assertTrue(b.get_config().has_explicit_nickname())
360
 
 
361
 
    def test_config_url(self):
362
 
        """The Branch.get_config will use section that uses a local url"""
363
 
        branch = self.make_branch('branch')
364
 
        self.assertEqual('branch', branch.nick)
365
 
 
366
 
        locations = config.locations_config_filename()
367
 
        config.ensure_config_dir_exists()
368
 
        local_url = urlutils.local_path_to_url('branch')
369
 
        open(locations, 'wb').write('[%s]\nnickname = foobar' 
370
 
                                    % (local_url,))
371
 
        self.assertEqual('foobar', branch.nick)
372
 
 
373
 
    def test_config_local_path(self):
374
 
        """The Branch.get_config will use a local system path"""
375
 
        branch = self.make_branch('branch')
376
 
        self.assertEqual('branch', branch.nick)
377
 
 
378
 
        locations = config.locations_config_filename()
379
 
        config.ensure_config_dir_exists()
380
 
        open(locations, 'wb').write('[%s/branch]\nnickname = barry' 
381
 
                                    % (osutils.getcwd().encode('utf8'),))
382
 
        self.assertEqual('barry', branch.nick)
383
 
 
384
 
    def test_config_creates_local(self):
385
 
        """Creating a new entry in config uses a local path."""
386
 
        branch = self.make_branch('branch')
387
 
        branch.set_push_location('http://foobar')
388
 
        locations = config.locations_config_filename()
389
 
        local_path = osutils.getcwd().encode('utf8')
390
 
        # Surprisingly ConfigObj doesn't create a trailing newline
391
 
        self.check_file_contents(locations,
392
 
            '[%s/branch]\npush_location = http://foobar' % (local_path,))
393
 
 
394
 
 
395
 
class TestGlobalConfigItems(TestCase):
 
79
            config.ConfigParser = oldparserclass
 
80
        self.failUnless(isinstance(parser, InstrumentedConfigParser))
 
81
        self.assertEqual(parser._calls, [('read', [config.config_filename()])])
 
82
 
 
83
 
 
84
class TestConfigItems(TestCase):
 
85
 
 
86
    def setUp(self):
 
87
        super(TestConfigItems, self).setUp()
 
88
        self.bzr_email = os.environ.get('BZREMAIL')
 
89
        if self.bzr_email is not None:
 
90
            del os.environ['BZREMAIL']
 
91
        self.email = os.environ.get('EMAIL')
 
92
        if self.email is not None:
 
93
            del os.environ['EMAIL']
 
94
        self.oldenv = os.environ.get('HOME', None)
 
95
        os.environ['HOME'] = os.getcwd()
 
96
 
 
97
    def tearDown(self):
 
98
        os.environ['HOME'] = self.oldenv
 
99
        if self.bzr_email is not None:
 
100
            os.environ['BZREMAIL'] = bzr_email
 
101
        if self.email is not None:
 
102
            os.environ['EMAIL'] = email
 
103
        super(TestConfigItems, self).tearDown()
396
104
 
397
105
    def test_user_id(self):
398
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
399
 
        my_config = config.GlobalConfig()
400
 
        my_config._parser = my_config._get_parser(file=config_file)
401
 
        self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
402
 
                         my_config._get_user_id())
 
106
        config_file = StringIO(sample_config_text)
 
107
        parser = config._get_config_parser(file=config_file)
 
108
        self.assertEqual("Robert Collins <robertc@example.com>",
 
109
                         config._get_user_id(parser = parser))
403
110
 
404
111
    def test_absent_user_id(self):
405
112
        config_file = StringIO("")
406
 
        my_config = config.GlobalConfig()
407
 
        my_config._parser = my_config._get_parser(file=config_file)
408
 
        self.assertEqual(None, my_config._get_user_id())
409
 
 
410
 
    def test_configured_editor(self):
411
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
412
 
        my_config = config.GlobalConfig()
413
 
        my_config._parser = my_config._get_parser(file=config_file)
414
 
        self.assertEqual("vim", my_config.get_editor())
415
 
 
416
 
    def test_signatures_always(self):
417
 
        config_file = StringIO(sample_always_signatures)
418
 
        my_config = config.GlobalConfig()
419
 
        my_config._parser = my_config._get_parser(file=config_file)
420
 
        self.assertEqual(config.CHECK_NEVER,
421
 
                         my_config.signature_checking())
422
 
        self.assertEqual(config.SIGN_ALWAYS,
423
 
                         my_config.signing_policy())
424
 
        self.assertEqual(True, my_config.signature_needed())
425
 
 
426
 
    def test_signatures_if_possible(self):
427
 
        config_file = StringIO(sample_maybe_signatures)
428
 
        my_config = config.GlobalConfig()
429
 
        my_config._parser = my_config._get_parser(file=config_file)
430
 
        self.assertEqual(config.CHECK_NEVER,
431
 
                         my_config.signature_checking())
432
 
        self.assertEqual(config.SIGN_WHEN_REQUIRED,
433
 
                         my_config.signing_policy())
434
 
        self.assertEqual(False, my_config.signature_needed())
435
 
 
436
 
    def test_signatures_ignore(self):
437
 
        config_file = StringIO(sample_ignore_signatures)
438
 
        my_config = config.GlobalConfig()
439
 
        my_config._parser = my_config._get_parser(file=config_file)
440
 
        self.assertEqual(config.CHECK_ALWAYS,
441
 
                         my_config.signature_checking())
442
 
        self.assertEqual(config.SIGN_NEVER,
443
 
                         my_config.signing_policy())
444
 
        self.assertEqual(False, my_config.signature_needed())
445
 
 
446
 
    def _get_sample_config(self):
447
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
448
 
        my_config = config.GlobalConfig()
449
 
        my_config._parser = my_config._get_parser(file=config_file)
450
 
        return my_config
451
 
 
452
 
    def test_gpg_signing_command(self):
453
 
        my_config = self._get_sample_config()
454
 
        self.assertEqual("gnome-gpg", my_config.gpg_signing_command())
455
 
        self.assertEqual(False, my_config.signature_needed())
456
 
 
457
 
    def _get_empty_config(self):
458
 
        config_file = StringIO("")
459
 
        my_config = config.GlobalConfig()
460
 
        my_config._parser = my_config._get_parser(file=config_file)
461
 
        return my_config
462
 
 
463
 
    def test_gpg_signing_command_unset(self):
464
 
        my_config = self._get_empty_config()
465
 
        self.assertEqual("gpg", my_config.gpg_signing_command())
466
 
 
467
 
    def test_get_user_option_default(self):
468
 
        my_config = self._get_empty_config()
469
 
        self.assertEqual(None, my_config.get_user_option('no_option'))
470
 
 
471
 
    def test_get_user_option_global(self):
472
 
        my_config = self._get_sample_config()
473
 
        self.assertEqual("something",
474
 
                         my_config.get_user_option('user_global_option'))
475
 
        
476
 
    def test_post_commit_default(self):
477
 
        my_config = self._get_sample_config()
478
 
        self.assertEqual(None, my_config.post_commit())
479
 
 
480
 
    def test_configured_logformat(self):
481
 
        my_config = self._get_sample_config()
482
 
        self.assertEqual("short", my_config.log_format())
483
 
 
484
 
    def test_get_alias(self):
485
 
        my_config = self._get_sample_config()
486
 
        self.assertEqual('help', my_config.get_alias('h'))
487
 
 
488
 
    def test_get_no_alias(self):
489
 
        my_config = self._get_sample_config()
490
 
        self.assertEqual(None, my_config.get_alias('foo'))
491
 
 
492
 
    def test_get_long_alias(self):
493
 
        my_config = self._get_sample_config()
494
 
        self.assertEqual(sample_long_alias, my_config.get_alias('ll'))
495
 
 
496
 
 
497
 
class TestLocationConfig(TestCaseInTempDir):
498
 
 
499
 
    def test_constructs(self):
500
 
        my_config = config.LocationConfig('http://example.com')
501
 
        self.assertRaises(TypeError, config.LocationConfig)
502
 
 
503
 
    def test_branch_calls_read_filenames(self):
504
 
        # This is testing the correct file names are provided.
505
 
        # TODO: consolidate with the test for GlobalConfigs filename checks.
506
 
        #
507
 
        # replace the class that is constructured, to check its parameters
508
 
        oldparserclass = config.ConfigObj
509
 
        config.ConfigObj = InstrumentedConfigObj
510
 
        try:
511
 
            my_config = config.LocationConfig('http://www.example.com')
512
 
            parser = my_config._get_parser()
513
 
        finally:
514
 
            config.ConfigObj = oldparserclass
515
 
        self.failUnless(isinstance(parser, InstrumentedConfigObj))
516
 
        self.assertEqual(parser._calls,
517
 
                         [('__init__', config.locations_config_filename(),
518
 
                           'utf-8')])
519
 
        config.ensure_config_dir_exists()
520
 
        #os.mkdir(config.config_dir())
521
 
        f = file(config.branches_config_filename(), 'wb')
522
 
        f.write('')
523
 
        f.close()
524
 
        oldparserclass = config.ConfigObj
525
 
        config.ConfigObj = InstrumentedConfigObj
526
 
        try:
527
 
            my_config = config.LocationConfig('http://www.example.com')
528
 
            parser = my_config._get_parser()
529
 
        finally:
530
 
            config.ConfigObj = oldparserclass
531
 
 
532
 
    def test_get_global_config(self):
533
 
        my_config = config.BranchConfig(FakeBranch('http://example.com'))
534
 
        global_config = my_config._get_global_config()
535
 
        self.failUnless(isinstance(global_config, config.GlobalConfig))
536
 
        self.failUnless(global_config is my_config._get_global_config())
537
 
 
538
 
    def test__get_section_no_match(self):
539
 
        self.get_branch_config('/')
540
 
        self.assertEqual(None, self.my_location_config._get_section())
541
 
        
542
 
    def test__get_section_exact(self):
543
 
        self.get_branch_config('http://www.example.com')
544
 
        self.assertEqual('http://www.example.com',
545
 
                         self.my_location_config._get_section())
546
 
   
547
 
    def test__get_section_suffix_does_not(self):
548
 
        self.get_branch_config('http://www.example.com-com')
549
 
        self.assertEqual(None, self.my_location_config._get_section())
550
 
 
551
 
    def test__get_section_subdir_recursive(self):
552
 
        self.get_branch_config('http://www.example.com/com')
553
 
        self.assertEqual('http://www.example.com',
554
 
                         self.my_location_config._get_section())
555
 
 
556
 
    def test__get_section_subdir_matches(self):
557
 
        self.get_branch_config('http://www.example.com/useglobal')
558
 
        self.assertEqual('http://www.example.com/useglobal',
559
 
                         self.my_location_config._get_section())
560
 
 
561
 
    def test__get_section_subdir_nonrecursive(self):
562
 
        self.get_branch_config(
563
 
            'http://www.example.com/useglobal/childbranch')
564
 
        self.assertEqual('http://www.example.com',
565
 
                         self.my_location_config._get_section())
566
 
 
567
 
    def test__get_section_subdir_trailing_slash(self):
568
 
        self.get_branch_config('/b')
569
 
        self.assertEqual('/b/', self.my_location_config._get_section())
570
 
 
571
 
    def test__get_section_subdir_child(self):
572
 
        self.get_branch_config('/a/foo')
573
 
        self.assertEqual('/a/*', self.my_location_config._get_section())
574
 
 
575
 
    def test__get_section_subdir_child_child(self):
576
 
        self.get_branch_config('/a/foo/bar')
577
 
        self.assertEqual('/a/', self.my_location_config._get_section())
578
 
 
579
 
    def test__get_section_trailing_slash_with_children(self):
580
 
        self.get_branch_config('/a/')
581
 
        self.assertEqual('/a/', self.my_location_config._get_section())
582
 
 
583
 
    def test__get_section_explicit_over_glob(self):
584
 
        self.get_branch_config('/a/c')
585
 
        self.assertEqual('/a/c', self.my_location_config._get_section())
586
 
 
587
 
 
588
 
    def test_location_without_username(self):
589
 
        self.get_branch_config('http://www.example.com/useglobal')
590
 
        self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
591
 
                         self.my_config.username())
592
 
 
593
 
    def test_location_not_listed(self):
594
 
        """Test that the global username is used when no location matches"""
595
 
        self.get_branch_config('/home/robertc/sources')
596
 
        self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
597
 
                         self.my_config.username())
598
 
 
599
 
    def test_overriding_location(self):
600
 
        self.get_branch_config('http://www.example.com/foo')
601
 
        self.assertEqual('Robert Collins <robertc@example.org>',
602
 
                         self.my_config.username())
603
 
 
604
 
    def test_signatures_not_set(self):
605
 
        self.get_branch_config('http://www.example.com',
606
 
                                 global_config=sample_ignore_signatures)
607
 
        self.assertEqual(config.CHECK_ALWAYS,
608
 
                         self.my_config.signature_checking())
609
 
        self.assertEqual(config.SIGN_NEVER,
610
 
                         self.my_config.signing_policy())
611
 
 
612
 
    def test_signatures_never(self):
613
 
        self.get_branch_config('/a/c')
614
 
        self.assertEqual(config.CHECK_NEVER,
615
 
                         self.my_config.signature_checking())
616
 
        
617
 
    def test_signatures_when_available(self):
618
 
        self.get_branch_config('/a/', global_config=sample_ignore_signatures)
619
 
        self.assertEqual(config.CHECK_IF_POSSIBLE,
620
 
                         self.my_config.signature_checking())
621
 
        
622
 
    def test_signatures_always(self):
623
 
        self.get_branch_config('/b')
624
 
        self.assertEqual(config.CHECK_ALWAYS,
625
 
                         self.my_config.signature_checking())
626
 
        
627
 
    def test_gpg_signing_command(self):
628
 
        self.get_branch_config('/b')
629
 
        self.assertEqual("gnome-gpg", self.my_config.gpg_signing_command())
630
 
 
631
 
    def test_gpg_signing_command_missing(self):
632
 
        self.get_branch_config('/a')
633
 
        self.assertEqual("false", self.my_config.gpg_signing_command())
634
 
 
635
 
    def test_get_user_option_global(self):
636
 
        self.get_branch_config('/a')
637
 
        self.assertEqual('something',
638
 
                         self.my_config.get_user_option('user_global_option'))
639
 
 
640
 
    def test_get_user_option_local(self):
641
 
        self.get_branch_config('/a')
642
 
        self.assertEqual('local',
643
 
                         self.my_config.get_user_option('user_local_option'))
644
 
        
645
 
    def test_post_commit_default(self):
646
 
        self.get_branch_config('/a/c')
647
 
        self.assertEqual('bzrlib.tests.test_config.post_commit',
648
 
                         self.my_config.post_commit())
649
 
 
650
 
    def get_branch_config(self, location, global_config=None):
651
 
        if global_config is None:
652
 
            global_file = StringIO(sample_config_text.encode('utf-8'))
653
 
        else:
654
 
            global_file = StringIO(global_config.encode('utf-8'))
655
 
        branches_file = StringIO(sample_branches_text.encode('utf-8'))
656
 
        self.my_config = config.BranchConfig(FakeBranch(location))
657
 
        # Force location config to use specified file
658
 
        self.my_location_config = self.my_config._get_location_config()
659
 
        self.my_location_config._get_parser(branches_file)
660
 
        # Force global config to use specified file
661
 
        self.my_config._get_global_config()._get_parser(global_file)
662
 
 
663
 
    def test_set_user_setting_sets_and_saves(self):
664
 
        self.get_branch_config('/a/c')
665
 
        record = InstrumentedConfigObj("foo")
666
 
        self.my_location_config._parser = record
667
 
 
668
 
        real_mkdir = os.mkdir
669
 
        self.created = False
670
 
        def checked_mkdir(path, mode=0777):
671
 
            self.log('making directory: %s', path)
672
 
            real_mkdir(path, mode)
673
 
            self.created = True
674
 
 
675
 
        os.mkdir = checked_mkdir
676
 
        try:
677
 
            self.my_config.set_user_option('foo', 'bar', local=True)
678
 
        finally:
679
 
            os.mkdir = real_mkdir
680
 
 
681
 
        self.failUnless(self.created, 'Failed to create ~/.bazaar')
682
 
        self.assertEqual([('__contains__', '/a/c'),
683
 
                          ('__contains__', '/a/c/'),
684
 
                          ('__setitem__', '/a/c', {}),
685
 
                          ('__getitem__', '/a/c'),
686
 
                          ('__setitem__', 'foo', 'bar'),
687
 
                          ('write',)],
688
 
                         record._calls[1:])
689
 
 
690
 
    def test_set_user_setting_sets_and_saves2(self):
691
 
        self.get_branch_config('/a/c')
692
 
        self.assertIs(self.my_config.get_user_option('foo'), None)
693
 
        self.my_config.set_user_option('foo', 'bar')
694
 
        self.assertEqual(
695
 
            self.my_config.branch.control_files.files['branch.conf'], 
696
 
            'foo = bar')
697
 
        self.assertEqual(self.my_config.get_user_option('foo'), 'bar')
698
 
        self.my_config.set_user_option('foo', 'baz', local=True)
699
 
        self.assertEqual(self.my_config.get_user_option('foo'), 'baz')
700
 
        self.my_config.set_user_option('foo', 'qux')
701
 
        self.assertEqual(self.my_config.get_user_option('foo'), 'baz')
702
 
        
703
 
 
704
 
precedence_global = 'option = global'
705
 
precedence_branch = 'option = branch'
706
 
precedence_location = """
707
 
[http://]
708
 
recurse = true
709
 
option = recurse
710
 
[http://example.com/specific]
711
 
option = exact
712
 
"""
713
 
 
714
 
 
715
 
class TestBranchConfigItems(TestCaseInTempDir):
716
 
 
717
 
    def get_branch_config(self, global_config=None, location=None, 
718
 
                          location_config=None, branch_data_config=None):
719
 
        my_config = config.BranchConfig(FakeBranch(location))
720
 
        if global_config is not None:
721
 
            global_file = StringIO(global_config.encode('utf-8'))
722
 
            my_config._get_global_config()._get_parser(global_file)
723
 
        self.my_location_config = my_config._get_location_config()
724
 
        if location_config is not None:
725
 
            location_file = StringIO(location_config.encode('utf-8'))
726
 
            self.my_location_config._get_parser(location_file)
727
 
        if branch_data_config is not None:
728
 
            my_config.branch.control_files.files['branch.conf'] = \
729
 
                branch_data_config
730
 
        return my_config
731
 
 
732
 
    def test_user_id(self):
733
 
        branch = FakeBranch(user_id='Robert Collins <robertc@example.net>')
734
 
        my_config = config.BranchConfig(branch)
735
 
        self.assertEqual("Robert Collins <robertc@example.net>",
736
 
                         my_config.username())
737
 
        branch.control_files.email = "John"
738
 
        my_config.set_user_option('email', 
739
 
                                  "Robert Collins <robertc@example.org>")
740
 
        self.assertEqual("John", my_config.username())
741
 
        branch.control_files.email = None
742
 
        self.assertEqual("Robert Collins <robertc@example.org>",
743
 
                         my_config.username())
744
 
 
745
 
    def test_not_set_in_branch(self):
746
 
        my_config = self.get_branch_config(sample_config_text)
747
 
        my_config.branch.control_files.email = None
748
 
        self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
749
 
                         my_config._get_user_id())
750
 
        my_config.branch.control_files.email = "John"
751
 
        self.assertEqual("John", my_config._get_user_id())
752
 
 
753
 
    def test_BZREMAIL_OVERRIDES(self):
754
 
        os.environ['BZREMAIL'] = "Robert Collins <robertc@example.org>"
755
 
        branch = FakeBranch()
756
 
        my_config = config.BranchConfig(branch)
757
 
        self.assertEqual("Robert Collins <robertc@example.org>",
758
 
                         my_config.username())
759
 
    
760
 
    def test_signatures_forced(self):
761
 
        my_config = self.get_branch_config(
762
 
            global_config=sample_always_signatures)
763
 
        self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
764
 
        self.assertEqual(config.SIGN_ALWAYS, my_config.signing_policy())
765
 
        self.assertTrue(my_config.signature_needed())
766
 
 
767
 
    def test_signatures_forced_branch(self):
768
 
        my_config = self.get_branch_config(
769
 
            global_config=sample_ignore_signatures,
770
 
            branch_data_config=sample_always_signatures)
771
 
        self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
772
 
        self.assertEqual(config.SIGN_ALWAYS, my_config.signing_policy())
773
 
        self.assertTrue(my_config.signature_needed())
774
 
 
775
 
    def test_gpg_signing_command(self):
776
 
        my_config = self.get_branch_config(
777
 
            # branch data cannot set gpg_signing_command
778
 
            branch_data_config="gpg_signing_command=pgp")
779
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
780
 
        my_config._get_global_config()._get_parser(config_file)
781
 
        self.assertEqual('gnome-gpg', my_config.gpg_signing_command())
782
 
 
783
 
    def test_get_user_option_global(self):
784
 
        branch = FakeBranch()
785
 
        my_config = config.BranchConfig(branch)
786
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
787
 
        (my_config._get_global_config()._get_parser(config_file))
788
 
        self.assertEqual('something',
789
 
                         my_config.get_user_option('user_global_option'))
790
 
 
791
 
    def test_post_commit_default(self):
792
 
        branch = FakeBranch()
793
 
        my_config = self.get_branch_config(sample_config_text, '/a/c',
794
 
                                           sample_branches_text)
795
 
        self.assertEqual(my_config.branch.base, '/a/c')
796
 
        self.assertEqual('bzrlib.tests.test_config.post_commit',
797
 
                         my_config.post_commit())
798
 
        my_config.set_user_option('post_commit', 'rmtree_root')
799
 
        # post-commit is ignored when bresent in branch data
800
 
        self.assertEqual('bzrlib.tests.test_config.post_commit',
801
 
                         my_config.post_commit())
802
 
        my_config.set_user_option('post_commit', 'rmtree_root', local=True)
803
 
        self.assertEqual('rmtree_root', my_config.post_commit())
804
 
 
805
 
    def test_config_precedence(self):
806
 
        my_config = self.get_branch_config(global_config=precedence_global)
807
 
        self.assertEqual(my_config.get_user_option('option'), 'global')
808
 
        my_config = self.get_branch_config(global_config=precedence_global, 
809
 
                                      branch_data_config=precedence_branch)
810
 
        self.assertEqual(my_config.get_user_option('option'), 'branch')
811
 
        my_config = self.get_branch_config(global_config=precedence_global, 
812
 
                                      branch_data_config=precedence_branch,
813
 
                                      location_config=precedence_location)
814
 
        self.assertEqual(my_config.get_user_option('option'), 'recurse')
815
 
        my_config = self.get_branch_config(global_config=precedence_global, 
816
 
                                      branch_data_config=precedence_branch,
817
 
                                      location_config=precedence_location,
818
 
                                      location='http://example.com/specific')
819
 
        self.assertEqual(my_config.get_user_option('option'), 'exact')
820
 
 
821
 
 
822
 
class TestMailAddressExtraction(TestCase):
823
 
 
824
 
    def test_extract_email_address(self):
825
 
        self.assertEqual('jane@test.com',
826
 
                         config.extract_email_address('Jane <jane@test.com>'))
827
 
        self.assertRaises(errors.BzrError,
828
 
                          config.extract_email_address, 'Jane Tester')
 
113
        parser = config._get_config_parser(file=config_file)
 
114
        self.assertEqual(None,
 
115
                         config._get_user_id(parser = parser))