~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_config.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-03-22 12:17:00 UTC
  • mfrom: (1616.1.10 bzr.mbp.integration)
  • Revision ID: pqm@pqm.ubuntu.com-20060322121700-79ce0be81013aba1
(mbp) pycurl fixes, other fixes, weave commands, verbose commit changes from robert

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 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
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
 
    trace,
32
 
    )
33
 
from bzrlib.branch import Branch
34
 
from bzrlib.bzrdir import BzrDir
35
 
from bzrlib.tests import TestCase, TestCaseInTempDir, TestCaseWithTransport
 
26
import bzrlib.config as config
 
27
import bzrlib.errors as errors
 
28
from bzrlib.tests import TestCase, TestCaseInTempDir
36
29
 
37
30
 
38
31
sample_long_alias="log -r-15..-1 --line"
39
 
sample_config_text = u"""
40
 
[DEFAULT]
41
 
email=Erik B\u00e5gfors <erik@bagfors.nu>
42
 
editor=vim
43
 
gpg_signing_command=gnome-gpg
44
 
log_format=short
45
 
user_global_option=something
46
 
[ALIASES]
47
 
h=help
48
 
ll=""" + sample_long_alias + "\n"
49
 
 
50
 
 
51
 
sample_always_signatures = """
52
 
[DEFAULT]
53
 
check_signatures=ignore
54
 
create_signatures=always
55
 
"""
56
 
 
57
 
sample_ignore_signatures = """
58
 
[DEFAULT]
59
 
check_signatures=require
60
 
create_signatures=never
61
 
"""
62
 
 
63
 
sample_maybe_signatures = """
64
 
[DEFAULT]
65
 
check_signatures=ignore
66
 
create_signatures=when-required
67
 
"""
68
 
 
69
 
sample_branches_text = """
70
 
[http://www.example.com]
71
 
# Top level policy
72
 
email=Robert Collins <robertc@example.org>
73
 
normal_option = normal
74
 
appendpath_option = append
75
 
appendpath_option:policy = appendpath
76
 
norecurse_option = norecurse
77
 
norecurse_option:policy = norecurse
78
 
[http://www.example.com/ignoreparent]
79
 
# different project: ignore parent dir config
80
 
ignore_parents=true
81
 
[http://www.example.com/norecurse]
82
 
# configuration items that only apply to this dir
83
 
recurse=false
84
 
normal_option = norecurse
85
 
[http://www.example.com/dir]
86
 
appendpath_option = normal
87
 
[/b/]
88
 
check_signatures=require
89
 
# test trailing / matching with no children
90
 
[/a/]
91
 
check_signatures=check-available
92
 
gpg_signing_command=false
93
 
user_local_option=local
94
 
# test trailing / matching
95
 
[/a/*]
96
 
#subdirs will match but not the parent
97
 
[/a/c]
98
 
check_signatures=ignore
99
 
post_commit=bzrlib.tests.test_config.post_commit
100
 
#testing explicit beats globs
101
 
"""
 
32
sample_config_text = ("[DEFAULT]\n"
 
33
                      u"email=Erik B\u00e5gfors <erik@bagfors.nu>\n"
 
34
                      "editor=vim\n"
 
35
                      "gpg_signing_command=gnome-gpg\n"
 
36
                      "log_format=short\n"
 
37
                      "user_global_option=something\n"
 
38
                      "[ALIASES]\n"
 
39
                      "h=help\n"
 
40
                      "ll=" + sample_long_alias + "\n")
 
41
 
 
42
 
 
43
sample_always_signatures = ("[DEFAULT]\n"
 
44
                            "check_signatures=require\n")
 
45
 
 
46
 
 
47
sample_ignore_signatures = ("[DEFAULT]\n"
 
48
                            "check_signatures=ignore\n")
 
49
 
 
50
 
 
51
sample_maybe_signatures = ("[DEFAULT]\n"
 
52
                            "check_signatures=check-available\n")
 
53
 
 
54
 
 
55
sample_branches_text = ("[http://www.example.com]\n"
 
56
                        "# Top level policy\n"
 
57
                        "email=Robert Collins <robertc@example.org>\n"
 
58
                        "[http://www.example.com/useglobal]\n"
 
59
                        "# different project, forces global lookup\n"
 
60
                        "recurse=false\n"
 
61
                        "[/b/]\n"
 
62
                        "check_signatures=require\n"
 
63
                        "# test trailing / matching with no children\n"
 
64
                        "[/a/]\n"
 
65
                        "check_signatures=check-available\n"
 
66
                        "gpg_signing_command=false\n"
 
67
                        "user_local_option=local\n"
 
68
                        "# test trailing / matching\n"
 
69
                        "[/a/*]\n"
 
70
                        "#subdirs will match but not the parent\n"
 
71
                        "recurse=False\n"
 
72
                        "[/a/c]\n"
 
73
                        "check_signatures=ignore\n"
 
74
                        "post_commit=bzrlib.tests.test_config.post_commit\n"
 
75
                        "#testing explicit beats globs\n")
 
76
 
102
77
 
103
78
 
104
79
class InstrumentedConfigObj(object):
118
93
    def __setitem__(self, key, value):
119
94
        self._calls.append(('__setitem__', key, value))
120
95
 
121
 
    def __delitem__(self, key):
122
 
        self._calls.append(('__delitem__', key))
123
 
 
124
 
    def keys(self):
125
 
        self._calls.append(('keys',))
126
 
        return []
127
 
 
128
 
    def write(self, arg):
 
96
    def write(self):
129
97
        self._calls.append(('write',))
130
98
 
131
 
    def as_bool(self, value):
132
 
        self._calls.append(('as_bool', value))
133
 
        return False
134
 
 
135
 
    def get_value(self, section, name):
136
 
        self._calls.append(('get_value', section, name))
137
 
        return None
138
 
 
139
99
 
140
100
class FakeBranch(object):
141
101
 
142
 
    def __init__(self, base=None, user_id=None):
143
 
        if base is None:
144
 
            self.base = "http://example.com/branches/demo"
145
 
        else:
146
 
            self.base = base
147
 
        self.control_files = FakeControlFiles(user_id=user_id)
148
 
 
149
 
    def lock_write(self):
150
 
        pass
151
 
 
152
 
    def unlock(self):
153
 
        pass
 
102
    def __init__(self):
 
103
        self.base = "http://example.com/branches/demo"
 
104
        self.control_files = FakeControlFiles()
154
105
 
155
106
 
156
107
class FakeControlFiles(object):
157
108
 
158
 
    def __init__(self, user_id=None):
159
 
        self.email = user_id
160
 
        self.files = {}
 
109
    def __init__(self):
 
110
        self.email = 'Robert Collins <robertc@example.net>\n'
161
111
 
162
112
    def get_utf8(self, filename):
163
113
        if filename != 'email':
166
116
            return StringIO(self.email)
167
117
        raise errors.NoSuchFile(filename)
168
118
 
169
 
    def get(self, filename):
170
 
        try:
171
 
            return StringIO(self.files[filename])
172
 
        except KeyError:
173
 
            raise errors.NoSuchFile(filename)
174
 
 
175
 
    def put(self, filename, fileobj):
176
 
        self.files[filename] = fileobj.read()
177
 
 
178
119
 
179
120
class InstrumentedConfig(config.Config):
180
121
    """An instrumented config that supplies stubs for template methods."""
231
172
 
232
173
    def test_signatures_default(self):
233
174
        my_config = config.Config()
234
 
        self.assertFalse(my_config.signature_needed())
235
175
        self.assertEqual(config.CHECK_IF_POSSIBLE,
236
176
                         my_config.signature_checking())
237
 
        self.assertEqual(config.SIGN_WHEN_REQUIRED,
238
 
                         my_config.signing_policy())
239
177
 
240
178
    def test_signatures_template_method(self):
241
179
        my_config = InstrumentedConfig()
270
208
 
271
209
    def setUp(self):
272
210
        super(TestConfigPath, self).setUp()
 
211
        self.old_home = os.environ.get('HOME', None)
 
212
        self.old_appdata = os.environ.get('APPDATA', None)
273
213
        os.environ['HOME'] = '/home/bogus'
274
 
        if sys.platform == 'win32':
275
 
            os.environ['BZR_HOME'] = \
276
 
                r'C:\Documents and Settings\bogus\Application Data'
 
214
        os.environ['APPDATA'] = \
 
215
            r'C:\Documents and Settings\bogus\Application Data'
277
216
 
 
217
    def tearDown(self):
 
218
        if self.old_home is None:
 
219
            del os.environ['HOME']
 
220
        else:
 
221
            os.environ['HOME'] = self.old_home
 
222
        if self.old_appdata is None:
 
223
            del os.environ['APPDATA']
 
224
        else:
 
225
            os.environ['APPDATA'] = self.old_appdata
 
226
        super(TestConfigPath, self).tearDown()
 
227
    
278
228
    def test_config_dir(self):
279
229
        if sys.platform == 'win32':
280
230
            self.assertEqual(config.config_dir(), 
298
248
            self.assertEqual(config.branches_config_filename(),
299
249
                             '/home/bogus/.bazaar/branches.conf')
300
250
 
301
 
    def test_locations_config_filename(self):
302
 
        if sys.platform == 'win32':
303
 
            self.assertEqual(config.locations_config_filename(), 
304
 
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0/locations.conf')
305
 
        else:
306
 
            self.assertEqual(config.locations_config_filename(),
307
 
                             '/home/bogus/.bazaar/locations.conf')
308
 
 
309
251
class TestIniConfig(TestCase):
310
252
 
311
253
    def test_contructs(self):
344
286
                                          'utf-8')])
345
287
 
346
288
 
347
 
class TestBranchConfig(TestCaseWithTransport):
 
289
class TestBranchConfig(TestCaseInTempDir):
348
290
 
349
291
    def test_constructs(self):
350
292
        branch = FakeBranch()
358
300
        self.assertEqual(branch.base, location_config.location)
359
301
        self.failUnless(location_config is my_config._get_location_config())
360
302
 
361
 
    def test_get_config(self):
362
 
        """The Branch.get_config method works properly"""
363
 
        b = BzrDir.create_standalone_workingtree('.').branch
364
 
        my_config = b.get_config()
365
 
        self.assertIs(my_config.get_user_option('wacky'), None)
366
 
        my_config.set_user_option('wacky', 'unlikely')
367
 
        self.assertEqual(my_config.get_user_option('wacky'), 'unlikely')
368
 
 
369
 
        # Ensure we get the same thing if we start again
370
 
        b2 = Branch.open('.')
371
 
        my_config2 = b2.get_config()
372
 
        self.assertEqual(my_config2.get_user_option('wacky'), 'unlikely')
373
 
 
374
 
    def test_has_explicit_nickname(self):
375
 
        b = self.make_branch('.')
376
 
        self.assertFalse(b.get_config().has_explicit_nickname())
377
 
        b.nick = 'foo'
378
 
        self.assertTrue(b.get_config().has_explicit_nickname())
379
 
 
380
 
    def test_config_url(self):
381
 
        """The Branch.get_config will use section that uses a local url"""
382
 
        branch = self.make_branch('branch')
383
 
        self.assertEqual('branch', branch.nick)
384
 
 
385
 
        locations = config.locations_config_filename()
386
 
        config.ensure_config_dir_exists()
387
 
        local_url = urlutils.local_path_to_url('branch')
388
 
        open(locations, 'wb').write('[%s]\nnickname = foobar' 
389
 
                                    % (local_url,))
390
 
        self.assertEqual('foobar', branch.nick)
391
 
 
392
 
    def test_config_local_path(self):
393
 
        """The Branch.get_config will use a local system path"""
394
 
        branch = self.make_branch('branch')
395
 
        self.assertEqual('branch', branch.nick)
396
 
 
397
 
        locations = config.locations_config_filename()
398
 
        config.ensure_config_dir_exists()
399
 
        open(locations, 'wb').write('[%s/branch]\nnickname = barry' 
400
 
                                    % (osutils.getcwd().encode('utf8'),))
401
 
        self.assertEqual('barry', branch.nick)
402
 
 
403
 
    def test_config_creates_local(self):
404
 
        """Creating a new entry in config uses a local path."""
405
 
        branch = self.make_branch('branch', format='knit')
406
 
        branch.set_push_location('http://foobar')
407
 
        locations = config.locations_config_filename()
408
 
        local_path = osutils.getcwd().encode('utf8')
409
 
        # Surprisingly ConfigObj doesn't create a trailing newline
410
 
        self.check_file_contents(locations,
411
 
            '[%s/branch]\npush_location = http://foobar\npush_location:policy = norecurse' % (local_path,))
412
 
 
413
 
    def test_autonick_urlencoded(self):
414
 
        b = self.make_branch('!repo')
415
 
        self.assertEqual('!repo', b.get_config().get_nickname())
416
 
 
417
 
    def test_warn_if_masked(self):
418
 
        _warning = trace.warning
419
 
        warnings = []
420
 
        def warning(*args):
421
 
            warnings.append(args[0] % args[1:])
422
 
 
423
 
        def set_option(store, warn_masked=True):
424
 
            warnings[:] = []
425
 
            conf.set_user_option('example_option', repr(store), store=store,
426
 
                                 warn_masked=warn_masked)
427
 
        def assertWarning(warning):
428
 
            if warning is None:
429
 
                self.assertEqual(0, len(warnings))
430
 
            else:
431
 
                self.assertEqual(1, len(warnings))
432
 
                self.assertEqual(warning, warnings[0])
433
 
        trace.warning = warning
434
 
        try:
435
 
            branch = self.make_branch('.')
436
 
            conf = branch.get_config()
437
 
            set_option(config.STORE_GLOBAL)
438
 
            assertWarning(None)
439
 
            set_option(config.STORE_BRANCH)
440
 
            assertWarning(None)
441
 
            set_option(config.STORE_GLOBAL)
442
 
            assertWarning('Value "4" is masked by "3" from branch.conf')
443
 
            set_option(config.STORE_GLOBAL, warn_masked=False)
444
 
            assertWarning(None)
445
 
            set_option(config.STORE_LOCATION)
446
 
            assertWarning(None)
447
 
            set_option(config.STORE_BRANCH)
448
 
            assertWarning('Value "3" is masked by "0" from locations.conf')
449
 
            set_option(config.STORE_BRANCH, warn_masked=False)
450
 
            assertWarning(None)
451
 
        finally:
452
 
            trace.warning = _warning
453
 
 
454
303
 
455
304
class TestGlobalConfigItems(TestCase):
456
305
 
477
326
        config_file = StringIO(sample_always_signatures)
478
327
        my_config = config.GlobalConfig()
479
328
        my_config._parser = my_config._get_parser(file=config_file)
480
 
        self.assertEqual(config.CHECK_NEVER,
 
329
        self.assertEqual(config.CHECK_ALWAYS,
481
330
                         my_config.signature_checking())
482
 
        self.assertEqual(config.SIGN_ALWAYS,
483
 
                         my_config.signing_policy())
484
331
        self.assertEqual(True, my_config.signature_needed())
485
332
 
486
333
    def test_signatures_if_possible(self):
487
334
        config_file = StringIO(sample_maybe_signatures)
488
335
        my_config = config.GlobalConfig()
489
336
        my_config._parser = my_config._get_parser(file=config_file)
490
 
        self.assertEqual(config.CHECK_NEVER,
 
337
        self.assertEqual(config.CHECK_IF_POSSIBLE,
491
338
                         my_config.signature_checking())
492
 
        self.assertEqual(config.SIGN_WHEN_REQUIRED,
493
 
                         my_config.signing_policy())
494
339
        self.assertEqual(False, my_config.signature_needed())
495
340
 
496
341
    def test_signatures_ignore(self):
497
342
        config_file = StringIO(sample_ignore_signatures)
498
343
        my_config = config.GlobalConfig()
499
344
        my_config._parser = my_config._get_parser(file=config_file)
500
 
        self.assertEqual(config.CHECK_ALWAYS,
 
345
        self.assertEqual(config.CHECK_NEVER,
501
346
                         my_config.signature_checking())
502
 
        self.assertEqual(config.SIGN_NEVER,
503
 
                         my_config.signing_policy())
504
347
        self.assertEqual(False, my_config.signature_needed())
505
348
 
506
349
    def _get_sample_config(self):
553
396
        my_config = self._get_sample_config()
554
397
        self.assertEqual(sample_long_alias, my_config.get_alias('ll'))
555
398
 
556
 
 
557
 
class TestLocationConfig(TestCaseInTempDir):
 
399
class TestLocationConfig(TestCase):
558
400
 
559
401
    def test_constructs(self):
560
402
        my_config = config.LocationConfig('http://example.com')
567
409
        # replace the class that is constructured, to check its parameters
568
410
        oldparserclass = config.ConfigObj
569
411
        config.ConfigObj = InstrumentedConfigObj
 
412
        my_config = config.LocationConfig('http://www.example.com')
570
413
        try:
571
 
            my_config = config.LocationConfig('http://www.example.com')
572
414
            parser = my_config._get_parser()
573
415
        finally:
574
416
            config.ConfigObj = oldparserclass
575
417
        self.failUnless(isinstance(parser, InstrumentedConfigObj))
576
418
        self.assertEqual(parser._calls,
577
 
                         [('__init__', config.locations_config_filename(),
578
 
                           'utf-8')])
579
 
        config.ensure_config_dir_exists()
580
 
        #os.mkdir(config.config_dir())
581
 
        f = file(config.branches_config_filename(), 'wb')
582
 
        f.write('')
583
 
        f.close()
584
 
        oldparserclass = config.ConfigObj
585
 
        config.ConfigObj = InstrumentedConfigObj
586
 
        try:
587
 
            my_config = config.LocationConfig('http://www.example.com')
588
 
            parser = my_config._get_parser()
589
 
        finally:
590
 
            config.ConfigObj = oldparserclass
 
419
                         [('__init__', config.branches_config_filename())])
591
420
 
592
421
    def test_get_global_config(self):
593
 
        my_config = config.BranchConfig(FakeBranch('http://example.com'))
 
422
        my_config = config.LocationConfig('http://example.com')
594
423
        global_config = my_config._get_global_config()
595
424
        self.failUnless(isinstance(global_config, config.GlobalConfig))
596
425
        self.failUnless(global_config is my_config._get_global_config())
597
426
 
598
 
    def test__get_matching_sections_no_match(self):
599
 
        self.get_branch_config('/')
600
 
        self.assertEqual([], self.my_location_config._get_matching_sections())
 
427
    def test__get_section_no_match(self):
 
428
        self.get_location_config('/')
 
429
        self.assertEqual(None, self.my_config._get_section())
601
430
        
602
 
    def test__get_matching_sections_exact(self):
603
 
        self.get_branch_config('http://www.example.com')
604
 
        self.assertEqual([('http://www.example.com', '')],
605
 
                         self.my_location_config._get_matching_sections())
 
431
    def test__get_section_exact(self):
 
432
        self.get_location_config('http://www.example.com')
 
433
        self.assertEqual('http://www.example.com',
 
434
                         self.my_config._get_section())
606
435
   
607
 
    def test__get_matching_sections_suffix_does_not(self):
608
 
        self.get_branch_config('http://www.example.com-com')
609
 
        self.assertEqual([], self.my_location_config._get_matching_sections())
610
 
 
611
 
    def test__get_matching_sections_subdir_recursive(self):
612
 
        self.get_branch_config('http://www.example.com/com')
613
 
        self.assertEqual([('http://www.example.com', 'com')],
614
 
                         self.my_location_config._get_matching_sections())
615
 
 
616
 
    def test__get_matching_sections_ignoreparent(self):
617
 
        self.get_branch_config('http://www.example.com/ignoreparent')
618
 
        self.assertEqual([('http://www.example.com/ignoreparent', '')],
619
 
                         self.my_location_config._get_matching_sections())
620
 
 
621
 
    def test__get_matching_sections_ignoreparent_subdir(self):
622
 
        self.get_branch_config(
623
 
            'http://www.example.com/ignoreparent/childbranch')
624
 
        self.assertEqual([('http://www.example.com/ignoreparent', 'childbranch')],
625
 
                         self.my_location_config._get_matching_sections())
626
 
 
627
 
    def test__get_matching_sections_subdir_trailing_slash(self):
628
 
        self.get_branch_config('/b')
629
 
        self.assertEqual([('/b/', '')],
630
 
                         self.my_location_config._get_matching_sections())
631
 
 
632
 
    def test__get_matching_sections_subdir_child(self):
633
 
        self.get_branch_config('/a/foo')
634
 
        self.assertEqual([('/a/*', ''), ('/a/', 'foo')],
635
 
                         self.my_location_config._get_matching_sections())
636
 
 
637
 
    def test__get_matching_sections_subdir_child_child(self):
638
 
        self.get_branch_config('/a/foo/bar')
639
 
        self.assertEqual([('/a/*', 'bar'), ('/a/', 'foo/bar')],
640
 
                         self.my_location_config._get_matching_sections())
641
 
 
642
 
    def test__get_matching_sections_trailing_slash_with_children(self):
643
 
        self.get_branch_config('/a/')
644
 
        self.assertEqual([('/a/', '')],
645
 
                         self.my_location_config._get_matching_sections())
646
 
 
647
 
    def test__get_matching_sections_explicit_over_glob(self):
648
 
        # XXX: 2006-09-08 jamesh
649
 
        # This test only passes because ord('c') > ord('*').  If there
650
 
        # was a config section for '/a/?', it would get precedence
651
 
        # over '/a/c'.
652
 
        self.get_branch_config('/a/c')
653
 
        self.assertEqual([('/a/c', ''), ('/a/*', ''), ('/a/', 'c')],
654
 
                         self.my_location_config._get_matching_sections())
655
 
 
656
 
    def test__get_option_policy_normal(self):
657
 
        self.get_branch_config('http://www.example.com')
658
 
        self.assertEqual(
659
 
            self.my_location_config._get_config_policy(
660
 
            'http://www.example.com', 'normal_option'),
661
 
            config.POLICY_NONE)
662
 
 
663
 
    def test__get_option_policy_norecurse(self):
664
 
        self.get_branch_config('http://www.example.com')
665
 
        self.assertEqual(
666
 
            self.my_location_config._get_option_policy(
667
 
            'http://www.example.com', 'norecurse_option'),
668
 
            config.POLICY_NORECURSE)
669
 
        # Test old recurse=False setting:
670
 
        self.assertEqual(
671
 
            self.my_location_config._get_option_policy(
672
 
            'http://www.example.com/norecurse', 'normal_option'),
673
 
            config.POLICY_NORECURSE)
674
 
 
675
 
    def test__get_option_policy_normal(self):
676
 
        self.get_branch_config('http://www.example.com')
677
 
        self.assertEqual(
678
 
            self.my_location_config._get_option_policy(
679
 
            'http://www.example.com', 'appendpath_option'),
680
 
            config.POLICY_APPENDPATH)
 
436
    def test__get_section_suffix_does_not(self):
 
437
        self.get_location_config('http://www.example.com-com')
 
438
        self.assertEqual(None, self.my_config._get_section())
 
439
 
 
440
    def test__get_section_subdir_recursive(self):
 
441
        self.get_location_config('http://www.example.com/com')
 
442
        self.assertEqual('http://www.example.com',
 
443
                         self.my_config._get_section())
 
444
 
 
445
    def test__get_section_subdir_matches(self):
 
446
        self.get_location_config('http://www.example.com/useglobal')
 
447
        self.assertEqual('http://www.example.com/useglobal',
 
448
                         self.my_config._get_section())
 
449
 
 
450
    def test__get_section_subdir_nonrecursive(self):
 
451
        self.get_location_config(
 
452
            'http://www.example.com/useglobal/childbranch')
 
453
        self.assertEqual('http://www.example.com',
 
454
                         self.my_config._get_section())
 
455
 
 
456
    def test__get_section_subdir_trailing_slash(self):
 
457
        self.get_location_config('/b')
 
458
        self.assertEqual('/b/', self.my_config._get_section())
 
459
 
 
460
    def test__get_section_subdir_child(self):
 
461
        self.get_location_config('/a/foo')
 
462
        self.assertEqual('/a/*', self.my_config._get_section())
 
463
 
 
464
    def test__get_section_subdir_child_child(self):
 
465
        self.get_location_config('/a/foo/bar')
 
466
        self.assertEqual('/a/', self.my_config._get_section())
 
467
 
 
468
    def test__get_section_trailing_slash_with_children(self):
 
469
        self.get_location_config('/a/')
 
470
        self.assertEqual('/a/', self.my_config._get_section())
 
471
 
 
472
    def test__get_section_explicit_over_glob(self):
 
473
        self.get_location_config('/a/c')
 
474
        self.assertEqual('/a/c', self.my_config._get_section())
 
475
 
 
476
    def get_location_config(self, location, global_config=None):
 
477
        if global_config is None:
 
478
            global_file = StringIO(sample_config_text)
 
479
        else:
 
480
            global_file = StringIO(global_config)
 
481
        branches_file = StringIO(sample_branches_text)
 
482
        self.my_config = config.LocationConfig(location)
 
483
        self.my_config._get_parser(branches_file)
 
484
        self.my_config._get_global_config()._get_parser(global_file)
681
485
 
682
486
    def test_location_without_username(self):
683
 
        self.get_branch_config('http://www.example.com/ignoreparent')
684
 
        self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
 
487
        self.get_location_config('http://www.example.com/useglobal')
 
488
        self.assertEqual('Robert Collins <robertc@example.com>',
685
489
                         self.my_config.username())
686
490
 
687
491
    def test_location_not_listed(self):
688
 
        """Test that the global username is used when no location matches"""
689
 
        self.get_branch_config('/home/robertc/sources')
690
 
        self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
 
492
        self.get_location_config('/home/robertc/sources')
 
493
        self.assertEqual('Robert Collins <robertc@example.com>',
691
494
                         self.my_config.username())
692
495
 
693
496
    def test_overriding_location(self):
694
 
        self.get_branch_config('http://www.example.com/foo')
 
497
        self.get_location_config('http://www.example.com/foo')
695
498
        self.assertEqual('Robert Collins <robertc@example.org>',
696
499
                         self.my_config.username())
697
500
 
698
501
    def test_signatures_not_set(self):
699
 
        self.get_branch_config('http://www.example.com',
 
502
        self.get_location_config('http://www.example.com',
700
503
                                 global_config=sample_ignore_signatures)
701
 
        self.assertEqual(config.CHECK_ALWAYS,
 
504
        self.assertEqual(config.CHECK_NEVER,
702
505
                         self.my_config.signature_checking())
703
 
        self.assertEqual(config.SIGN_NEVER,
704
 
                         self.my_config.signing_policy())
705
506
 
706
507
    def test_signatures_never(self):
707
 
        self.get_branch_config('/a/c')
 
508
        self.get_location_config('/a/c')
708
509
        self.assertEqual(config.CHECK_NEVER,
709
510
                         self.my_config.signature_checking())
710
511
        
711
512
    def test_signatures_when_available(self):
712
 
        self.get_branch_config('/a/', global_config=sample_ignore_signatures)
 
513
        self.get_location_config('/a/', global_config=sample_ignore_signatures)
713
514
        self.assertEqual(config.CHECK_IF_POSSIBLE,
714
515
                         self.my_config.signature_checking())
715
516
        
716
517
    def test_signatures_always(self):
717
 
        self.get_branch_config('/b')
 
518
        self.get_location_config('/b')
718
519
        self.assertEqual(config.CHECK_ALWAYS,
719
520
                         self.my_config.signature_checking())
720
521
        
721
522
    def test_gpg_signing_command(self):
722
 
        self.get_branch_config('/b')
 
523
        self.get_location_config('/b')
723
524
        self.assertEqual("gnome-gpg", self.my_config.gpg_signing_command())
724
525
 
725
526
    def test_gpg_signing_command_missing(self):
726
 
        self.get_branch_config('/a')
 
527
        self.get_location_config('/a')
727
528
        self.assertEqual("false", self.my_config.gpg_signing_command())
728
529
 
729
530
    def test_get_user_option_global(self):
730
 
        self.get_branch_config('/a')
 
531
        self.get_location_config('/a')
731
532
        self.assertEqual('something',
732
533
                         self.my_config.get_user_option('user_global_option'))
733
534
 
734
535
    def test_get_user_option_local(self):
735
 
        self.get_branch_config('/a')
 
536
        self.get_location_config('/a')
736
537
        self.assertEqual('local',
737
538
                         self.my_config.get_user_option('user_local_option'))
738
 
 
739
 
    def test_get_user_option_appendpath(self):
740
 
        # returned as is for the base path:
741
 
        self.get_branch_config('http://www.example.com')
742
 
        self.assertEqual('append',
743
 
                         self.my_config.get_user_option('appendpath_option'))
744
 
        # Extra path components get appended:
745
 
        self.get_branch_config('http://www.example.com/a/b/c')
746
 
        self.assertEqual('append/a/b/c',
747
 
                         self.my_config.get_user_option('appendpath_option'))
748
 
        # Overriden for http://www.example.com/dir, where it is a
749
 
        # normal option:
750
 
        self.get_branch_config('http://www.example.com/dir/a/b/c')
751
 
        self.assertEqual('normal',
752
 
                         self.my_config.get_user_option('appendpath_option'))
753
 
 
754
 
    def test_get_user_option_norecurse(self):
755
 
        self.get_branch_config('http://www.example.com')
756
 
        self.assertEqual('norecurse',
757
 
                         self.my_config.get_user_option('norecurse_option'))
758
 
        self.get_branch_config('http://www.example.com/dir')
759
 
        self.assertEqual(None,
760
 
                         self.my_config.get_user_option('norecurse_option'))
761
 
        # http://www.example.com/norecurse is a recurse=False section
762
 
        # that redefines normal_option.  Subdirectories do not pick up
763
 
        # this redefinition.
764
 
        self.get_branch_config('http://www.example.com/norecurse')
765
 
        self.assertEqual('norecurse',
766
 
                         self.my_config.get_user_option('normal_option'))
767
 
        self.get_branch_config('http://www.example.com/norecurse/subdir')
768
 
        self.assertEqual('normal',
769
 
                         self.my_config.get_user_option('normal_option'))
770
 
 
771
 
    def test_set_user_option_norecurse(self):
772
 
        self.get_branch_config('http://www.example.com')
773
 
        self.my_config.set_user_option('foo', 'bar',
774
 
                                       store=config.STORE_LOCATION_NORECURSE)
775
 
        self.assertEqual(
776
 
            self.my_location_config._get_option_policy(
777
 
            'http://www.example.com', 'foo'),
778
 
            config.POLICY_NORECURSE)
779
 
 
780
 
    def test_set_user_option_appendpath(self):
781
 
        self.get_branch_config('http://www.example.com')
782
 
        self.my_config.set_user_option('foo', 'bar',
783
 
                                       store=config.STORE_LOCATION_APPENDPATH)
784
 
        self.assertEqual(
785
 
            self.my_location_config._get_option_policy(
786
 
            'http://www.example.com', 'foo'),
787
 
            config.POLICY_APPENDPATH)
788
 
 
789
 
    def test_set_user_option_change_policy(self):
790
 
        self.get_branch_config('http://www.example.com')
791
 
        self.my_config.set_user_option('norecurse_option', 'normal',
792
 
                                       store=config.STORE_LOCATION)
793
 
        self.assertEqual(
794
 
            self.my_location_config._get_option_policy(
795
 
            'http://www.example.com', 'norecurse_option'),
796
 
            config.POLICY_NONE)
797
 
 
798
 
    def test_set_user_option_recurse_false_section(self):
799
 
        # The following section has recurse=False set.  The test is to
800
 
        # make sure that a normal option can be added to the section,
801
 
        # converting recurse=False to the norecurse policy.
802
 
        self.get_branch_config('http://www.example.com/norecurse')
803
 
        self.callDeprecated(['The recurse option is deprecated as of 0.14.  '
804
 
                             'The section "http://www.example.com/norecurse" '
805
 
                             'has been converted to use policies.'],
806
 
                            self.my_config.set_user_option,
807
 
                            'foo', 'bar', store=config.STORE_LOCATION)
808
 
        self.assertEqual(
809
 
            self.my_location_config._get_option_policy(
810
 
            'http://www.example.com/norecurse', 'foo'),
811
 
            config.POLICY_NONE)
812
 
        # The previously existing option is still norecurse:
813
 
        self.assertEqual(
814
 
            self.my_location_config._get_option_policy(
815
 
            'http://www.example.com/norecurse', 'normal_option'),
816
 
            config.POLICY_NORECURSE)
817
 
 
 
539
        
818
540
    def test_post_commit_default(self):
819
 
        self.get_branch_config('/a/c')
 
541
        self.get_location_config('/a/c')
820
542
        self.assertEqual('bzrlib.tests.test_config.post_commit',
821
543
                         self.my_config.post_commit())
822
544
 
823
 
    def get_branch_config(self, location, global_config=None):
 
545
 
 
546
class TestLocationConfig(TestCaseInTempDir):
 
547
 
 
548
    def get_location_config(self, location, global_config=None):
824
549
        if global_config is None:
825
550
            global_file = StringIO(sample_config_text.encode('utf-8'))
826
551
        else:
827
552
            global_file = StringIO(global_config.encode('utf-8'))
828
553
        branches_file = StringIO(sample_branches_text.encode('utf-8'))
829
 
        self.my_config = config.BranchConfig(FakeBranch(location))
830
 
        # Force location config to use specified file
831
 
        self.my_location_config = self.my_config._get_location_config()
832
 
        self.my_location_config._get_parser(branches_file)
833
 
        # Force global config to use specified file
 
554
        self.my_config = config.LocationConfig(location)
 
555
        self.my_config._get_parser(branches_file)
834
556
        self.my_config._get_global_config()._get_parser(global_file)
835
557
 
836
558
    def test_set_user_setting_sets_and_saves(self):
837
 
        self.get_branch_config('/a/c')
 
559
        self.get_location_config('/a/c')
838
560
        record = InstrumentedConfigObj("foo")
839
 
        self.my_location_config._parser = record
 
561
        self.my_config._parser = record
840
562
 
841
563
        real_mkdir = os.mkdir
842
564
        self.created = False
847
569
 
848
570
        os.mkdir = checked_mkdir
849
571
        try:
850
 
            self.callDeprecated(['The recurse option is deprecated as of '
851
 
                                 '0.14.  The section "/a/c" has been '
852
 
                                 'converted to use policies.'],
853
 
                                self.my_config.set_user_option,
854
 
                                'foo', 'bar', store=config.STORE_LOCATION)
 
572
            self.my_config.set_user_option('foo', 'bar')
855
573
        finally:
856
574
            os.mkdir = real_mkdir
857
575
 
861
579
                          ('__setitem__', '/a/c', {}),
862
580
                          ('__getitem__', '/a/c'),
863
581
                          ('__setitem__', 'foo', 'bar'),
864
 
                          ('__getitem__', '/a/c'),
865
 
                          ('as_bool', 'recurse'),
866
 
                          ('__getitem__', '/a/c'),
867
 
                          ('__delitem__', 'recurse'),
868
 
                          ('__getitem__', '/a/c'),
869
 
                          ('keys',),
870
 
                          ('__getitem__', '/a/c'),
871
 
                          ('__contains__', 'foo:policy'),
872
582
                          ('write',)],
873
583
                         record._calls[1:])
874
584
 
875
 
    def test_set_user_setting_sets_and_saves2(self):
876
 
        self.get_branch_config('/a/c')
877
 
        self.assertIs(self.my_config.get_user_option('foo'), None)
878
 
        self.my_config.set_user_option('foo', 'bar')
879
 
        self.assertEqual(
880
 
            self.my_config.branch.control_files.files['branch.conf'], 
881
 
            'foo = bar')
882
 
        self.assertEqual(self.my_config.get_user_option('foo'), 'bar')
883
 
        self.my_config.set_user_option('foo', 'baz',
884
 
                                       store=config.STORE_LOCATION)
885
 
        self.assertEqual(self.my_config.get_user_option('foo'), 'baz')
886
 
        self.my_config.set_user_option('foo', 'qux')
887
 
        self.assertEqual(self.my_config.get_user_option('foo'), 'baz')
888
 
        
889
 
 
890
 
precedence_global = 'option = global'
891
 
precedence_branch = 'option = branch'
892
 
precedence_location = """
893
 
[http://]
894
 
recurse = true
895
 
option = recurse
896
 
[http://example.com/specific]
897
 
option = exact
898
 
"""
899
 
 
900
 
 
901
 
class TestBranchConfigItems(TestCaseInTempDir):
902
 
 
903
 
    def get_branch_config(self, global_config=None, location=None, 
904
 
                          location_config=None, branch_data_config=None):
905
 
        my_config = config.BranchConfig(FakeBranch(location))
906
 
        if global_config is not None:
907
 
            global_file = StringIO(global_config.encode('utf-8'))
908
 
            my_config._get_global_config()._get_parser(global_file)
909
 
        self.my_location_config = my_config._get_location_config()
910
 
        if location_config is not None:
911
 
            location_file = StringIO(location_config.encode('utf-8'))
912
 
            self.my_location_config._get_parser(location_file)
913
 
        if branch_data_config is not None:
914
 
            my_config.branch.control_files.files['branch.conf'] = \
915
 
                branch_data_config
916
 
        return my_config
 
585
 
 
586
class TestBranchConfigItems(TestCase):
917
587
 
918
588
    def test_user_id(self):
919
 
        branch = FakeBranch(user_id='Robert Collins <robertc@example.net>')
 
589
        branch = FakeBranch()
920
590
        my_config = config.BranchConfig(branch)
921
591
        self.assertEqual("Robert Collins <robertc@example.net>",
922
 
                         my_config.username())
 
592
                         my_config._get_user_id())
923
593
        branch.control_files.email = "John"
924
 
        my_config.set_user_option('email', 
925
 
                                  "Robert Collins <robertc@example.org>")
926
 
        self.assertEqual("John", my_config.username())
 
594
        self.assertEqual("John", my_config._get_user_id())
 
595
 
 
596
    def test_not_set_in_branch(self):
 
597
        branch = FakeBranch()
 
598
        my_config = config.BranchConfig(branch)
927
599
        branch.control_files.email = None
928
 
        self.assertEqual("Robert Collins <robertc@example.org>",
929
 
                         my_config.username())
930
 
 
931
 
    def test_not_set_in_branch(self):
932
 
        my_config = self.get_branch_config(sample_config_text)
933
 
        my_config.branch.control_files.email = None
 
600
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
601
        (my_config._get_location_config().
 
602
            _get_global_config()._get_parser(config_file))
934
603
        self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
935
604
                         my_config._get_user_id())
936
 
        my_config.branch.control_files.email = "John"
 
605
        branch.control_files.email = "John"
937
606
        self.assertEqual("John", my_config._get_user_id())
938
607
 
939
 
    def test_BZR_EMAIL_OVERRIDES(self):
940
 
        os.environ['BZR_EMAIL'] = "Robert Collins <robertc@example.org>"
 
608
    def test_BZREMAIL_OVERRIDES(self):
 
609
        os.environ['BZREMAIL'] = "Robert Collins <robertc@example.org>"
941
610
        branch = FakeBranch()
942
611
        my_config = config.BranchConfig(branch)
943
612
        self.assertEqual("Robert Collins <robertc@example.org>",
944
613
                         my_config.username())
945
614
    
946
615
    def test_signatures_forced(self):
947
 
        my_config = self.get_branch_config(
948
 
            global_config=sample_always_signatures)
949
 
        self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
950
 
        self.assertEqual(config.SIGN_ALWAYS, my_config.signing_policy())
951
 
        self.assertTrue(my_config.signature_needed())
952
 
 
953
 
    def test_signatures_forced_branch(self):
954
 
        my_config = self.get_branch_config(
955
 
            global_config=sample_ignore_signatures,
956
 
            branch_data_config=sample_always_signatures)
957
 
        self.assertEqual(config.CHECK_NEVER, my_config.signature_checking())
958
 
        self.assertEqual(config.SIGN_ALWAYS, my_config.signing_policy())
959
 
        self.assertTrue(my_config.signature_needed())
 
616
        branch = FakeBranch()
 
617
        my_config = config.BranchConfig(branch)
 
618
        config_file = StringIO(sample_always_signatures)
 
619
        (my_config._get_location_config().
 
620
            _get_global_config()._get_parser(config_file))
 
621
        self.assertEqual(config.CHECK_ALWAYS, my_config.signature_checking())
960
622
 
961
623
    def test_gpg_signing_command(self):
962
 
        my_config = self.get_branch_config(
963
 
            # branch data cannot set gpg_signing_command
964
 
            branch_data_config="gpg_signing_command=pgp")
 
624
        branch = FakeBranch()
 
625
        my_config = config.BranchConfig(branch)
965
626
        config_file = StringIO(sample_config_text.encode('utf-8'))
966
 
        my_config._get_global_config()._get_parser(config_file)
 
627
        (my_config._get_location_config().
 
628
            _get_global_config()._get_parser(config_file))
967
629
        self.assertEqual('gnome-gpg', my_config.gpg_signing_command())
968
630
 
969
631
    def test_get_user_option_global(self):
970
632
        branch = FakeBranch()
971
633
        my_config = config.BranchConfig(branch)
972
634
        config_file = StringIO(sample_config_text.encode('utf-8'))
973
 
        (my_config._get_global_config()._get_parser(config_file))
 
635
        (my_config._get_location_config().
 
636
            _get_global_config()._get_parser(config_file))
974
637
        self.assertEqual('something',
975
638
                         my_config.get_user_option('user_global_option'))
976
639
 
977
640
    def test_post_commit_default(self):
978
641
        branch = FakeBranch()
979
 
        my_config = self.get_branch_config(sample_config_text, '/a/c',
980
 
                                           sample_branches_text)
981
 
        self.assertEqual(my_config.branch.base, '/a/c')
982
 
        self.assertEqual('bzrlib.tests.test_config.post_commit',
983
 
                         my_config.post_commit())
984
 
        my_config.set_user_option('post_commit', 'rmtree_root')
985
 
        # post-commit is ignored when bresent in branch data
986
 
        self.assertEqual('bzrlib.tests.test_config.post_commit',
987
 
                         my_config.post_commit())
988
 
        my_config.set_user_option('post_commit', 'rmtree_root',
989
 
                                  store=config.STORE_LOCATION)
990
 
        self.assertEqual('rmtree_root', my_config.post_commit())
991
 
 
992
 
    def test_config_precedence(self):
993
 
        my_config = self.get_branch_config(global_config=precedence_global)
994
 
        self.assertEqual(my_config.get_user_option('option'), 'global')
995
 
        my_config = self.get_branch_config(global_config=precedence_global, 
996
 
                                      branch_data_config=precedence_branch)
997
 
        self.assertEqual(my_config.get_user_option('option'), 'branch')
998
 
        my_config = self.get_branch_config(global_config=precedence_global, 
999
 
                                      branch_data_config=precedence_branch,
1000
 
                                      location_config=precedence_location)
1001
 
        self.assertEqual(my_config.get_user_option('option'), 'recurse')
1002
 
        my_config = self.get_branch_config(global_config=precedence_global, 
1003
 
                                      branch_data_config=precedence_branch,
1004
 
                                      location_config=precedence_location,
1005
 
                                      location='http://example.com/specific')
1006
 
        self.assertEqual(my_config.get_user_option('option'), 'exact')
 
642
        branch.base='/a/c'
 
643
        my_config = config.BranchConfig(branch)
 
644
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
645
        (my_config._get_location_config().
 
646
            _get_global_config()._get_parser(config_file))
 
647
        branch_file = StringIO(sample_branches_text)
 
648
        my_config._get_location_config()._get_parser(branch_file)
 
649
        self.assertEqual('bzrlib.tests.test_config.post_commit',
 
650
                         my_config.post_commit())
1007
651
 
1008
652
 
1009
653
class TestMailAddressExtraction(TestCase):
1011
655
    def test_extract_email_address(self):
1012
656
        self.assertEqual('jane@test.com',
1013
657
                         config.extract_email_address('Jane <jane@test.com>'))
1014
 
        self.assertRaises(errors.NoEmailInUsername,
 
658
        self.assertRaises(errors.BzrError,
1015
659
                          config.extract_email_address, 'Jane Tester')
1016
 
 
1017
 
 
1018
 
class TestTreeConfig(TestCaseWithTransport):
1019
 
 
1020
 
    def test_get_value(self):
1021
 
        """Test that retreiving a value from a section is possible"""
1022
 
        branch = self.make_branch('.')
1023
 
        tree_config = config.TreeConfig(branch)
1024
 
        tree_config.set_option('value', 'key', 'SECTION')
1025
 
        tree_config.set_option('value2', 'key2')
1026
 
        tree_config.set_option('value3-top', 'key3')
1027
 
        tree_config.set_option('value3-section', 'key3', 'SECTION')
1028
 
        value = tree_config.get_option('key', 'SECTION')
1029
 
        self.assertEqual(value, 'value')
1030
 
        value = tree_config.get_option('key2')
1031
 
        self.assertEqual(value, 'value2')
1032
 
        self.assertEqual(tree_config.get_option('non-existant'), None)
1033
 
        value = tree_config.get_option('non-existant', 'SECTION')
1034
 
        self.assertEqual(value, None)
1035
 
        value = tree_config.get_option('non-existant', default='default')
1036
 
        self.assertEqual(value, 'default')
1037
 
        self.assertEqual(tree_config.get_option('key2', 'NOSECTION'), None)
1038
 
        value = tree_config.get_option('key2', 'NOSECTION', default='default')
1039
 
        self.assertEqual(value, 'default')
1040
 
        value = tree_config.get_option('key3')
1041
 
        self.assertEqual(value, 'value3-top')
1042
 
        value = tree_config.get_option('key3', 'SECTION')
1043
 
        self.assertEqual(value, 'value3-section')