~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_config.py

  • Committer: Andrew Bennetts
  • Date: 2010-10-08 04:25:10 UTC
  • mto: This revision was merged to the branch mainline in revision 5472.
  • Revision ID: andrew.bennetts@canonical.com-20101008042510-sg9vdhmnggilzxsk
Fix stray TAB in source.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2011 Canonical Ltd
 
1
# Copyright (C) 2005-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
21
21
import sys
22
22
import threading
23
23
 
24
 
 
25
 
from testtools import matchers
26
 
 
27
24
#import bzrlib specific imports here
28
25
from bzrlib import (
29
26
    branch,
33
30
    errors,
34
31
    osutils,
35
32
    mail_client,
36
 
    mergetools,
37
33
    ui,
38
34
    urlutils,
39
35
    tests,
40
36
    trace,
41
37
    transport,
42
38
    )
43
 
from bzrlib.tests import (
44
 
    features,
45
 
    TestSkipped,
46
 
    scenarios,
47
 
    )
 
39
from bzrlib.tests import features
48
40
from bzrlib.util.configobj import configobj
49
41
 
50
42
 
60
52
          'config_section': '.'}),]
61
53
 
62
54
 
63
 
load_tests = scenarios.load_tests_apply_scenarios
 
55
def load_tests(standard_tests, module, loader):
 
56
    suite = loader.suiteClass()
 
57
 
 
58
    lc_tests, remaining_tests = tests.split_suite_by_condition(
 
59
        standard_tests, tests.condition_isinstance((
 
60
                TestLockableConfig,
 
61
                )))
 
62
    tests.multiply_tests(lc_tests, lockable_config_scenarios(), suite)
 
63
    suite.addTest(remaining_tests)
 
64
    return suite
64
65
 
65
66
 
66
67
sample_long_alias="log -r-15..-1 --line"
72
73
gpg_signing_command=gnome-gpg
73
74
log_format=short
74
75
user_global_option=something
75
 
bzr.mergetool.sometool=sometool {base} {this} {other} -o {result}
76
 
bzr.mergetool.funkytool=funkytool "arg with spaces" {this_temp}
77
 
bzr.default_mergetool=sometool
78
76
[ALIASES]
79
77
h=help
80
78
ll=""" + sample_long_alias + "\n"
133
131
"""
134
132
 
135
133
 
136
 
def create_configs(test):
137
 
    """Create configuration files for a given test.
138
 
 
139
 
    This requires creating a tree (and populate the ``test.tree`` attribute)
140
 
    and its associated branch and will populate the following attributes:
141
 
 
142
 
    - branch_config: A BranchConfig for the associated branch.
143
 
 
144
 
    - locations_config : A LocationConfig for the associated branch
145
 
 
146
 
    - bazaar_config: A GlobalConfig.
147
 
 
148
 
    The tree and branch are created in a 'tree' subdirectory so the tests can
149
 
    still use the test directory to stay outside of the branch.
150
 
    """
151
 
    tree = test.make_branch_and_tree('tree')
152
 
    test.tree = tree
153
 
    test.branch_config = config.BranchConfig(tree.branch)
154
 
    test.locations_config = config.LocationConfig(tree.basedir)
155
 
    test.bazaar_config = config.GlobalConfig()
156
 
 
157
 
 
158
 
def create_configs_with_file_option(test):
159
 
    """Create configuration files with a ``file`` option set in each.
160
 
 
161
 
    This builds on ``create_configs`` and add one ``file`` option in each
162
 
    configuration with a value which allows identifying the configuration file.
163
 
    """
164
 
    create_configs(test)
165
 
    test.bazaar_config.set_user_option('file', 'bazaar')
166
 
    test.locations_config.set_user_option('file', 'locations')
167
 
    test.branch_config.set_user_option('file', 'branch')
168
 
 
169
 
 
170
 
class TestOptionsMixin:
171
 
 
172
 
    def assertOptions(self, expected, conf):
173
 
        # We don't care about the parser (as it will make tests hard to write
174
 
        # and error-prone anyway)
175
 
        self.assertThat([opt[:4] for opt in conf._get_options()],
176
 
                        matchers.Equals(expected))
177
 
 
178
 
 
179
134
class InstrumentedConfigObj(object):
180
135
    """A config obj look-enough-alike to record calls made to it."""
181
136
 
314
269
        """
315
270
        co = config.ConfigObj()
316
271
        co['test'] = 'foo#bar'
317
 
        outfile = StringIO()
318
 
        co.write(outfile=outfile)
319
 
        lines = outfile.getvalue().splitlines()
 
272
        lines = co.write()
320
273
        self.assertEqual(lines, ['test = "foo#bar"'])
321
274
        co2 = config.ConfigObj(lines)
322
275
        self.assertEqual(co2['test'], 'foo#bar')
323
276
 
324
 
    def test_triple_quotes(self):
325
 
        # Bug #710410: if the value string has triple quotes
326
 
        # then ConfigObj versions up to 4.7.2 will quote them wrong
327
 
        # and won't able to read them back
328
 
        triple_quotes_value = '''spam
329
 
""" that's my spam """
330
 
eggs'''
331
 
        co = config.ConfigObj()
332
 
        co['test'] = triple_quotes_value
333
 
        # While writing this test another bug in ConfigObj has been found:
334
 
        # method co.write() without arguments produces list of lines
335
 
        # one option per line, and multiline values are not split
336
 
        # across multiple lines,
337
 
        # and that breaks the parsing these lines back by ConfigObj.
338
 
        # This issue only affects test, but it's better to avoid
339
 
        # `co.write()` construct at all.
340
 
        # [bialix 20110222] bug report sent to ConfigObj's author
341
 
        outfile = StringIO()
342
 
        co.write(outfile=outfile)
343
 
        output = outfile.getvalue()
344
 
        # now we're trying to read it back
345
 
        co2 = config.ConfigObj(StringIO(output))
346
 
        self.assertEquals(triple_quotes_value, co2['test'])
347
 
 
348
277
 
349
278
erroneous_config = """[section] # line 1
350
279
good=good # line 2
433
362
 
434
363
    def setUp(self):
435
364
        super(TestConfigPath, self).setUp()
436
 
        self.overrideEnv('HOME', '/home/bogus')
437
 
        self.overrideEnv('XDG_CACHE_DIR', '')
 
365
        os.environ['HOME'] = '/home/bogus'
 
366
        os.environ['XDG_CACHE_DIR'] = ''
438
367
        if sys.platform == 'win32':
439
 
            self.overrideEnv(
440
 
                'BZR_HOME', r'C:\Documents and Settings\bogus\Application Data')
 
368
            os.environ['BZR_HOME'] = \
 
369
                r'C:\Documents and Settings\bogus\Application Data'
441
370
            self.bzr_home = \
442
371
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0'
443
372
        else:
463
392
            '/home/bogus/.cache')
464
393
 
465
394
 
466
 
class TestXDGConfigDir(tests.TestCaseInTempDir):
467
 
    # must be in temp dir because config tests for the existence of the bazaar
468
 
    # subdirectory of $XDG_CONFIG_HOME
469
 
 
470
 
    def setUp(self):
471
 
        if sys.platform in ('darwin', 'win32'):
472
 
            raise tests.TestNotApplicable(
473
 
                'XDG config dir not used on this platform')
474
 
        super(TestXDGConfigDir, self).setUp()
475
 
        self.overrideEnv('HOME', self.test_home_dir)
476
 
        # BZR_HOME overrides everything we want to test so unset it.
477
 
        self.overrideEnv('BZR_HOME', None)
478
 
 
479
 
    def test_xdg_config_dir_exists(self):
480
 
        """When ~/.config/bazaar exists, use it as the config dir."""
481
 
        newdir = osutils.pathjoin(self.test_home_dir, '.config', 'bazaar')
482
 
        os.makedirs(newdir)
483
 
        self.assertEqual(config.config_dir(), newdir)
484
 
 
485
 
    def test_xdg_config_home(self):
486
 
        """When XDG_CONFIG_HOME is set, use it."""
487
 
        xdgconfigdir = osutils.pathjoin(self.test_home_dir, 'xdgconfig')
488
 
        self.overrideEnv('XDG_CONFIG_HOME', xdgconfigdir)
489
 
        newdir = osutils.pathjoin(xdgconfigdir, 'bazaar')
490
 
        os.makedirs(newdir)
491
 
        self.assertEqual(config.config_dir(), newdir)
492
 
 
493
 
 
494
395
class TestIniConfig(tests.TestCaseInTempDir):
495
396
 
496
397
    def make_config_parser(self, s):
510
411
    def test_cached(self):
511
412
        my_config = config.IniBasedConfig.from_string(sample_config_text)
512
413
        parser = my_config._get_parser()
513
 
        self.assertTrue(my_config._get_parser() is parser)
 
414
        self.failUnless(my_config._get_parser() is parser)
514
415
 
515
416
    def _dummy_chown(self, path, uid, gid):
516
417
        self.path, self.uid, self.gid = path, uid, gid
541
442
            ' Use IniBasedConfig(_content=xxx) instead.'],
542
443
            conf._get_parser, file=config_file)
543
444
 
544
 
 
545
445
class TestIniConfigSaving(tests.TestCaseInTempDir):
546
446
 
547
447
    def test_cant_save_without_a_file_name(self):
555
455
        self.assertFileEqual(content, 'test.conf')
556
456
 
557
457
 
558
 
class TestIniConfigOptionExpansionDefaultValue(tests.TestCaseInTempDir):
559
 
    """What is the default value of expand for config options.
560
 
 
561
 
    This is an opt-in beta feature used to evaluate whether or not option
562
 
    references can appear in dangerous place raising exceptions, disapearing
563
 
    (and as such corrupting data) or if it's safe to activate the option by
564
 
    default.
565
 
 
566
 
    Note that these tests relies on config._expand_default_value being already
567
 
    overwritten in the parent class setUp.
568
 
    """
569
 
 
570
 
    def setUp(self):
571
 
        super(TestIniConfigOptionExpansionDefaultValue, self).setUp()
572
 
        self.config = None
573
 
        self.warnings = []
574
 
        def warning(*args):
575
 
            self.warnings.append(args[0] % args[1:])
576
 
        self.overrideAttr(trace, 'warning', warning)
577
 
 
578
 
    def get_config(self, expand):
579
 
        c = config.GlobalConfig.from_string('bzr.config.expand=%s' % (expand,),
580
 
                                            save=True)
581
 
        return c
582
 
 
583
 
    def assertExpandIs(self, expected):
584
 
        actual = config._get_expand_default_value()
585
 
        #self.config.get_user_option_as_bool('bzr.config.expand')
586
 
        self.assertEquals(expected, actual)
587
 
 
588
 
    def test_default_is_None(self):
589
 
        self.assertEquals(None, config._expand_default_value)
590
 
 
591
 
    def test_default_is_False_even_if_None(self):
592
 
        self.config = self.get_config(None)
593
 
        self.assertExpandIs(False)
594
 
 
595
 
    def test_default_is_False_even_if_invalid(self):
596
 
        self.config = self.get_config('<your choice>')
597
 
        self.assertExpandIs(False)
598
 
        # ...
599
 
        # Huh ? My choice is False ? Thanks, always happy to hear that :D
600
 
        # Wait, you've been warned !
601
 
        self.assertLength(1, self.warnings)
602
 
        self.assertEquals(
603
 
            'Value "<your choice>" is not a boolean for "bzr.config.expand"',
604
 
            self.warnings[0])
605
 
 
606
 
    def test_default_is_True(self):
607
 
        self.config = self.get_config(True)
608
 
        self.assertExpandIs(True)
609
 
        
610
 
    def test_default_is_False(self):
611
 
        self.config = self.get_config(False)
612
 
        self.assertExpandIs(False)
613
 
        
614
 
 
615
 
class TestIniConfigOptionExpansion(tests.TestCase):
616
 
    """Test option expansion from the IniConfig level.
617
 
 
618
 
    What we really want here is to test the Config level, but the class being
619
 
    abstract as far as storing values is concerned, this can't be done
620
 
    properly (yet).
621
 
    """
622
 
    # FIXME: This should be rewritten when all configs share a storage
623
 
    # implementation -- vila 2011-02-18
624
 
 
625
 
    def get_config(self, string=None):
626
 
        if string is None:
627
 
            string = ''
628
 
        c = config.IniBasedConfig.from_string(string)
629
 
        return c
630
 
 
631
 
    def assertExpansion(self, expected, conf, string, env=None):
632
 
        self.assertEquals(expected, conf.expand_options(string, env))
633
 
 
634
 
    def test_no_expansion(self):
635
 
        c = self.get_config('')
636
 
        self.assertExpansion('foo', c, 'foo')
637
 
 
638
 
    def test_env_adding_options(self):
639
 
        c = self.get_config('')
640
 
        self.assertExpansion('bar', c, '{foo}', {'foo': 'bar'})
641
 
 
642
 
    def test_env_overriding_options(self):
643
 
        c = self.get_config('foo=baz')
644
 
        self.assertExpansion('bar', c, '{foo}', {'foo': 'bar'})
645
 
 
646
 
    def test_simple_ref(self):
647
 
        c = self.get_config('foo=xxx')
648
 
        self.assertExpansion('xxx', c, '{foo}')
649
 
 
650
 
    def test_unknown_ref(self):
651
 
        c = self.get_config('')
652
 
        self.assertRaises(errors.ExpandingUnknownOption,
653
 
                          c.expand_options, '{foo}')
654
 
 
655
 
    def test_indirect_ref(self):
656
 
        c = self.get_config('''
657
 
foo=xxx
658
 
bar={foo}
659
 
''')
660
 
        self.assertExpansion('xxx', c, '{bar}')
661
 
 
662
 
    def test_embedded_ref(self):
663
 
        c = self.get_config('''
664
 
foo=xxx
665
 
bar=foo
666
 
''')
667
 
        self.assertExpansion('xxx', c, '{{bar}}')
668
 
 
669
 
    def test_simple_loop(self):
670
 
        c = self.get_config('foo={foo}')
671
 
        self.assertRaises(errors.OptionExpansionLoop, c.expand_options, '{foo}')
672
 
 
673
 
    def test_indirect_loop(self):
674
 
        c = self.get_config('''
675
 
foo={bar}
676
 
bar={baz}
677
 
baz={foo}''')
678
 
        e = self.assertRaises(errors.OptionExpansionLoop,
679
 
                              c.expand_options, '{foo}')
680
 
        self.assertEquals('foo->bar->baz', e.refs)
681
 
        self.assertEquals('{foo}', e.string)
682
 
 
683
 
    def test_list(self):
684
 
        conf = self.get_config('''
685
 
foo=start
686
 
bar=middle
687
 
baz=end
688
 
list={foo},{bar},{baz}
689
 
''')
690
 
        self.assertEquals(['start', 'middle', 'end'],
691
 
                           conf.get_user_option('list', expand=True))
692
 
 
693
 
    def test_cascading_list(self):
694
 
        conf = self.get_config('''
695
 
foo=start,{bar}
696
 
bar=middle,{baz}
697
 
baz=end
698
 
list={foo}
699
 
''')
700
 
        self.assertEquals(['start', 'middle', 'end'],
701
 
                           conf.get_user_option('list', expand=True))
702
 
 
703
 
    def test_pathological_hidden_list(self):
704
 
        conf = self.get_config('''
705
 
foo=bin
706
 
bar=go
707
 
start={foo
708
 
middle=},{
709
 
end=bar}
710
 
hidden={start}{middle}{end}
711
 
''')
712
 
        # Nope, it's either a string or a list, and the list wins as soon as a
713
 
        # ',' appears, so the string concatenation never occur.
714
 
        self.assertEquals(['{foo', '}', '{', 'bar}'],
715
 
                          conf.get_user_option('hidden', expand=True))
716
 
 
717
 
class TestLocationConfigOptionExpansion(tests.TestCaseInTempDir):
718
 
 
719
 
    def get_config(self, location, string=None):
720
 
        if string is None:
721
 
            string = ''
722
 
        # Since we don't save the config we won't strictly require to inherit
723
 
        # from TestCaseInTempDir, but an error occurs so quickly...
724
 
        c = config.LocationConfig.from_string(string, location)
725
 
        return c
726
 
 
727
 
    def test_dont_cross_unrelated_section(self):
728
 
        c = self.get_config('/another/branch/path','''
729
 
[/one/branch/path]
730
 
foo = hello
731
 
bar = {foo}/2
732
 
 
733
 
[/another/branch/path]
734
 
bar = {foo}/2
735
 
''')
736
 
        self.assertRaises(errors.ExpandingUnknownOption,
737
 
                          c.get_user_option, 'bar', expand=True)
738
 
 
739
 
    def test_cross_related_sections(self):
740
 
        c = self.get_config('/project/branch/path','''
741
 
[/project]
742
 
foo = qu
743
 
 
744
 
[/project/branch/path]
745
 
bar = {foo}ux
746
 
''')
747
 
        self.assertEquals('quux', c.get_user_option('bar', expand=True))
748
 
 
749
 
 
750
458
class TestIniBaseConfigOnDisk(tests.TestCaseInTempDir):
751
459
 
752
460
    def test_cannot_reload_without_name(self):
769
477
 
770
478
class TestLockableConfig(tests.TestCaseInTempDir):
771
479
 
772
 
    scenarios = lockable_config_scenarios()
773
 
 
774
480
    # Set by load_tests
775
481
    config_class = None
776
482
    config_args = None
962
668
            parser = my_config._get_parser()
963
669
        finally:
964
670
            config.ConfigObj = oldparserclass
965
 
        self.assertIsInstance(parser, InstrumentedConfigObj)
 
671
        self.failUnless(isinstance(parser, InstrumentedConfigObj))
966
672
        self.assertEqual(parser._calls, [('__init__', config.config_filename(),
967
673
                                          'utf-8')])
968
674
 
979
685
        my_config = config.BranchConfig(branch)
980
686
        location_config = my_config._get_location_config()
981
687
        self.assertEqual(branch.base, location_config.location)
982
 
        self.assertIs(location_config, my_config._get_location_config())
 
688
        self.failUnless(location_config is my_config._get_location_config())
983
689
 
984
690
    def test_get_config(self):
985
691
        """The Branch.get_config method works properly"""
1177
883
        change_editor = my_config.get_change_editor('old', 'new')
1178
884
        self.assertIs(None, change_editor)
1179
885
 
1180
 
    def test_get_merge_tools(self):
1181
 
        conf = self._get_sample_config()
1182
 
        tools = conf.get_merge_tools()
1183
 
        self.log(repr(tools))
1184
 
        self.assertEqual(
1185
 
            {u'funkytool' : u'funkytool "arg with spaces" {this_temp}',
1186
 
            u'sometool' : u'sometool {base} {this} {other} -o {result}'},
1187
 
            tools)
1188
 
 
1189
 
    def test_get_merge_tools_empty(self):
1190
 
        conf = self._get_empty_config()
1191
 
        tools = conf.get_merge_tools()
1192
 
        self.assertEqual({}, tools)
1193
 
 
1194
 
    def test_find_merge_tool(self):
1195
 
        conf = self._get_sample_config()
1196
 
        cmdline = conf.find_merge_tool('sometool')
1197
 
        self.assertEqual('sometool {base} {this} {other} -o {result}', cmdline)
1198
 
 
1199
 
    def test_find_merge_tool_not_found(self):
1200
 
        conf = self._get_sample_config()
1201
 
        cmdline = conf.find_merge_tool('DOES NOT EXIST')
1202
 
        self.assertIs(cmdline, None)
1203
 
 
1204
 
    def test_find_merge_tool_known(self):
1205
 
        conf = self._get_empty_config()
1206
 
        cmdline = conf.find_merge_tool('kdiff3')
1207
 
        self.assertEquals('kdiff3 {base} {this} {other} -o {result}', cmdline)
1208
 
 
1209
 
    def test_find_merge_tool_override_known(self):
1210
 
        conf = self._get_empty_config()
1211
 
        conf.set_user_option('bzr.mergetool.kdiff3', 'kdiff3 blah')
1212
 
        cmdline = conf.find_merge_tool('kdiff3')
1213
 
        self.assertEqual('kdiff3 blah', cmdline)
1214
 
 
1215
886
 
1216
887
class TestGlobalConfigSavingOptions(tests.TestCaseInTempDir):
1217
888
 
1235
906
        self.assertIs(None, new_config.get_alias('commit'))
1236
907
 
1237
908
 
1238
 
class TestLocationConfig(tests.TestCaseInTempDir, TestOptionsMixin):
 
909
class TestLocationConfig(tests.TestCaseInTempDir):
1239
910
 
1240
911
    def test_constructs(self):
1241
912
        my_config = config.LocationConfig('http://example.com')
1253
924
            parser = my_config._get_parser()
1254
925
        finally:
1255
926
            config.ConfigObj = oldparserclass
1256
 
        self.assertIsInstance(parser, InstrumentedConfigObj)
 
927
        self.failUnless(isinstance(parser, InstrumentedConfigObj))
1257
928
        self.assertEqual(parser._calls,
1258
929
                         [('__init__', config.locations_config_filename(),
1259
930
                           'utf-8')])
1261
932
    def test_get_global_config(self):
1262
933
        my_config = config.BranchConfig(FakeBranch('http://example.com'))
1263
934
        global_config = my_config._get_global_config()
1264
 
        self.assertIsInstance(global_config, config.GlobalConfig)
1265
 
        self.assertIs(global_config, my_config._get_global_config())
1266
 
 
1267
 
    def assertLocationMatching(self, expected):
1268
 
        self.assertEqual(expected,
1269
 
                         list(self.my_location_config._get_matching_sections()))
 
935
        self.failUnless(isinstance(global_config, config.GlobalConfig))
 
936
        self.failUnless(global_config is my_config._get_global_config())
1270
937
 
1271
938
    def test__get_matching_sections_no_match(self):
1272
939
        self.get_branch_config('/')
1273
 
        self.assertLocationMatching([])
 
940
        self.assertEqual([], self.my_location_config._get_matching_sections())
1274
941
 
1275
942
    def test__get_matching_sections_exact(self):
1276
943
        self.get_branch_config('http://www.example.com')
1277
 
        self.assertLocationMatching([('http://www.example.com', '')])
 
944
        self.assertEqual([('http://www.example.com', '')],
 
945
                         self.my_location_config._get_matching_sections())
1278
946
 
1279
947
    def test__get_matching_sections_suffix_does_not(self):
1280
948
        self.get_branch_config('http://www.example.com-com')
1281
 
        self.assertLocationMatching([])
 
949
        self.assertEqual([], self.my_location_config._get_matching_sections())
1282
950
 
1283
951
    def test__get_matching_sections_subdir_recursive(self):
1284
952
        self.get_branch_config('http://www.example.com/com')
1285
 
        self.assertLocationMatching([('http://www.example.com', 'com')])
 
953
        self.assertEqual([('http://www.example.com', 'com')],
 
954
                         self.my_location_config._get_matching_sections())
1286
955
 
1287
956
    def test__get_matching_sections_ignoreparent(self):
1288
957
        self.get_branch_config('http://www.example.com/ignoreparent')
1289
 
        self.assertLocationMatching([('http://www.example.com/ignoreparent',
1290
 
                                      '')])
 
958
        self.assertEqual([('http://www.example.com/ignoreparent', '')],
 
959
                         self.my_location_config._get_matching_sections())
1291
960
 
1292
961
    def test__get_matching_sections_ignoreparent_subdir(self):
1293
962
        self.get_branch_config(
1294
963
            'http://www.example.com/ignoreparent/childbranch')
1295
 
        self.assertLocationMatching([('http://www.example.com/ignoreparent',
1296
 
                                      'childbranch')])
 
964
        self.assertEqual([('http://www.example.com/ignoreparent',
 
965
                           'childbranch')],
 
966
                         self.my_location_config._get_matching_sections())
1297
967
 
1298
968
    def test__get_matching_sections_subdir_trailing_slash(self):
1299
969
        self.get_branch_config('/b')
1300
 
        self.assertLocationMatching([('/b/', '')])
 
970
        self.assertEqual([('/b/', '')],
 
971
                         self.my_location_config._get_matching_sections())
1301
972
 
1302
973
    def test__get_matching_sections_subdir_child(self):
1303
974
        self.get_branch_config('/a/foo')
1304
 
        self.assertLocationMatching([('/a/*', ''), ('/a/', 'foo')])
 
975
        self.assertEqual([('/a/*', ''), ('/a/', 'foo')],
 
976
                         self.my_location_config._get_matching_sections())
1305
977
 
1306
978
    def test__get_matching_sections_subdir_child_child(self):
1307
979
        self.get_branch_config('/a/foo/bar')
1308
 
        self.assertLocationMatching([('/a/*', 'bar'), ('/a/', 'foo/bar')])
 
980
        self.assertEqual([('/a/*', 'bar'), ('/a/', 'foo/bar')],
 
981
                         self.my_location_config._get_matching_sections())
1309
982
 
1310
983
    def test__get_matching_sections_trailing_slash_with_children(self):
1311
984
        self.get_branch_config('/a/')
1312
 
        self.assertLocationMatching([('/a/', '')])
 
985
        self.assertEqual([('/a/', '')],
 
986
                         self.my_location_config._get_matching_sections())
1313
987
 
1314
988
    def test__get_matching_sections_explicit_over_glob(self):
1315
989
        # XXX: 2006-09-08 jamesh
1317
991
        # was a config section for '/a/?', it would get precedence
1318
992
        # over '/a/c'.
1319
993
        self.get_branch_config('/a/c')
1320
 
        self.assertLocationMatching([('/a/c', ''), ('/a/*', ''), ('/a/', 'c')])
 
994
        self.assertEqual([('/a/c', ''), ('/a/*', ''), ('/a/', 'c')],
 
995
                         self.my_location_config._get_matching_sections())
1321
996
 
1322
997
    def test__get_option_policy_normal(self):
1323
998
        self.get_branch_config('http://www.example.com')
1345
1020
            'http://www.example.com', 'appendpath_option'),
1346
1021
            config.POLICY_APPENDPATH)
1347
1022
 
1348
 
    def test__get_options_with_policy(self):
1349
 
        self.get_branch_config('/dir/subdir',
1350
 
                               location_config="""\
1351
 
[/dir]
1352
 
other_url = /other-dir
1353
 
other_url:policy = appendpath
1354
 
[/dir/subdir]
1355
 
other_url = /other-subdir
1356
 
""")
1357
 
        self.assertOptions(
1358
 
            [(u'other_url', u'/other-subdir', u'/dir/subdir', 'locations'),
1359
 
             (u'other_url', u'/other-dir', u'/dir', 'locations'),
1360
 
             (u'other_url:policy', u'appendpath', u'/dir', 'locations')],
1361
 
            self.my_location_config)
1362
 
 
1363
1023
    def test_location_without_username(self):
1364
1024
        self.get_branch_config('http://www.example.com/ignoreparent')
1365
1025
        self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
1501
1161
        self.assertEqual('bzrlib.tests.test_config.post_commit',
1502
1162
                         self.my_config.post_commit())
1503
1163
 
1504
 
    def get_branch_config(self, location, global_config=None,
1505
 
                          location_config=None):
 
1164
    def get_branch_config(self, location, global_config=None):
1506
1165
        my_branch = FakeBranch(location)
1507
1166
        if global_config is None:
1508
1167
            global_config = sample_config_text
1509
 
        if location_config is None:
1510
 
            location_config = sample_branches_text
1511
1168
 
1512
1169
        my_global_config = config.GlobalConfig.from_string(global_config,
1513
1170
                                                           save=True)
1514
1171
        my_location_config = config.LocationConfig.from_string(
1515
 
            location_config, my_branch.base, save=True)
 
1172
            sample_branches_text, my_branch.base, save=True)
1516
1173
        my_config = config.BranchConfig(my_branch)
1517
1174
        self.my_config = my_config
1518
1175
        self.my_location_config = my_config._get_location_config()
1563
1220
        self.assertEqual('bzr', my_config.get_bzr_remote_path())
1564
1221
        my_config.set_user_option('bzr_remote_path', '/path-bzr')
1565
1222
        self.assertEqual('/path-bzr', my_config.get_bzr_remote_path())
1566
 
        self.overrideEnv('BZR_REMOTE_PATH', '/environ-bzr')
 
1223
        os.environ['BZR_REMOTE_PATH'] = '/environ-bzr'
1567
1224
        self.assertEqual('/environ-bzr', my_config.get_bzr_remote_path())
1568
1225
 
1569
1226
 
1615
1272
        self.assertEqual("John", my_config._get_user_id())
1616
1273
 
1617
1274
    def test_BZR_EMAIL_OVERRIDES(self):
1618
 
        self.overrideEnv('BZR_EMAIL', "Robert Collins <robertc@example.org>")
 
1275
        os.environ['BZR_EMAIL'] = "Robert Collins <robertc@example.org>"
1619
1276
        branch = FakeBranch()
1620
1277
        my_config = config.BranchConfig(branch)
1621
1278
        self.assertEqual("Robert Collins <robertc@example.org>",
1814
1471
        self.assertIs(None, bzrdir_config.get_default_stack_on())
1815
1472
 
1816
1473
 
1817
 
class TestConfigGetOptions(tests.TestCaseWithTransport, TestOptionsMixin):
1818
 
 
1819
 
    def setUp(self):
1820
 
        super(TestConfigGetOptions, self).setUp()
1821
 
        create_configs(self)
1822
 
 
1823
 
    # One variable in none of the above
1824
 
    def test_no_variable(self):
1825
 
        # Using branch should query branch, locations and bazaar
1826
 
        self.assertOptions([], self.branch_config)
1827
 
 
1828
 
    def test_option_in_bazaar(self):
1829
 
        self.bazaar_config.set_user_option('file', 'bazaar')
1830
 
        self.assertOptions([('file', 'bazaar', 'DEFAULT', 'bazaar')],
1831
 
                           self.bazaar_config)
1832
 
 
1833
 
    def test_option_in_locations(self):
1834
 
        self.locations_config.set_user_option('file', 'locations')
1835
 
        self.assertOptions(
1836
 
            [('file', 'locations', self.tree.basedir, 'locations')],
1837
 
            self.locations_config)
1838
 
 
1839
 
    def test_option_in_branch(self):
1840
 
        self.branch_config.set_user_option('file', 'branch')
1841
 
        self.assertOptions([('file', 'branch', 'DEFAULT', 'branch')],
1842
 
                           self.branch_config)
1843
 
 
1844
 
    def test_option_in_bazaar_and_branch(self):
1845
 
        self.bazaar_config.set_user_option('file', 'bazaar')
1846
 
        self.branch_config.set_user_option('file', 'branch')
1847
 
        self.assertOptions([('file', 'branch', 'DEFAULT', 'branch'),
1848
 
                            ('file', 'bazaar', 'DEFAULT', 'bazaar'),],
1849
 
                           self.branch_config)
1850
 
 
1851
 
    def test_option_in_branch_and_locations(self):
1852
 
        # Hmm, locations override branch :-/
1853
 
        self.locations_config.set_user_option('file', 'locations')
1854
 
        self.branch_config.set_user_option('file', 'branch')
1855
 
        self.assertOptions(
1856
 
            [('file', 'locations', self.tree.basedir, 'locations'),
1857
 
             ('file', 'branch', 'DEFAULT', 'branch'),],
1858
 
            self.branch_config)
1859
 
 
1860
 
    def test_option_in_bazaar_locations_and_branch(self):
1861
 
        self.bazaar_config.set_user_option('file', 'bazaar')
1862
 
        self.locations_config.set_user_option('file', 'locations')
1863
 
        self.branch_config.set_user_option('file', 'branch')
1864
 
        self.assertOptions(
1865
 
            [('file', 'locations', self.tree.basedir, 'locations'),
1866
 
             ('file', 'branch', 'DEFAULT', 'branch'),
1867
 
             ('file', 'bazaar', 'DEFAULT', 'bazaar'),],
1868
 
            self.branch_config)
1869
 
 
1870
 
 
1871
 
class TestConfigRemoveOption(tests.TestCaseWithTransport, TestOptionsMixin):
1872
 
 
1873
 
    def setUp(self):
1874
 
        super(TestConfigRemoveOption, self).setUp()
1875
 
        create_configs_with_file_option(self)
1876
 
 
1877
 
    def test_remove_in_locations(self):
1878
 
        self.locations_config.remove_user_option('file', self.tree.basedir)
1879
 
        self.assertOptions(
1880
 
            [('file', 'branch', 'DEFAULT', 'branch'),
1881
 
             ('file', 'bazaar', 'DEFAULT', 'bazaar'),],
1882
 
            self.branch_config)
1883
 
 
1884
 
    def test_remove_in_branch(self):
1885
 
        self.branch_config.remove_user_option('file')
1886
 
        self.assertOptions(
1887
 
            [('file', 'locations', self.tree.basedir, 'locations'),
1888
 
             ('file', 'bazaar', 'DEFAULT', 'bazaar'),],
1889
 
            self.branch_config)
1890
 
 
1891
 
    def test_remove_in_bazaar(self):
1892
 
        self.bazaar_config.remove_user_option('file')
1893
 
        self.assertOptions(
1894
 
            [('file', 'locations', self.tree.basedir, 'locations'),
1895
 
             ('file', 'branch', 'DEFAULT', 'branch'),],
1896
 
            self.branch_config)
1897
 
 
1898
 
 
1899
 
class TestConfigGetSections(tests.TestCaseWithTransport):
1900
 
 
1901
 
    def setUp(self):
1902
 
        super(TestConfigGetSections, self).setUp()
1903
 
        create_configs(self)
1904
 
 
1905
 
    def assertSectionNames(self, expected, conf, name=None):
1906
 
        """Check which sections are returned for a given config.
1907
 
 
1908
 
        If fallback configurations exist their sections can be included.
1909
 
 
1910
 
        :param expected: A list of section names.
1911
 
 
1912
 
        :param conf: The configuration that will be queried.
1913
 
 
1914
 
        :param name: An optional section name that will be passed to
1915
 
            get_sections().
1916
 
        """
1917
 
        sections = list(conf._get_sections(name))
1918
 
        self.assertLength(len(expected), sections)
1919
 
        self.assertEqual(expected, [name for name, _, _ in sections])
1920
 
 
1921
 
    def test_bazaar_default_section(self):
1922
 
        self.assertSectionNames(['DEFAULT'], self.bazaar_config)
1923
 
 
1924
 
    def test_locations_default_section(self):
1925
 
        # No sections are defined in an empty file
1926
 
        self.assertSectionNames([], self.locations_config)
1927
 
 
1928
 
    def test_locations_named_section(self):
1929
 
        self.locations_config.set_user_option('file', 'locations')
1930
 
        self.assertSectionNames([self.tree.basedir], self.locations_config)
1931
 
 
1932
 
    def test_locations_matching_sections(self):
1933
 
        loc_config = self.locations_config
1934
 
        loc_config.set_user_option('file', 'locations')
1935
 
        # We need to cheat a bit here to create an option in sections above and
1936
 
        # below the 'location' one.
1937
 
        parser = loc_config._get_parser()
1938
 
        # locations.cong deals with '/' ignoring native os.sep
1939
 
        location_names = self.tree.basedir.split('/')
1940
 
        parent = '/'.join(location_names[:-1])
1941
 
        child = '/'.join(location_names + ['child'])
1942
 
        parser[parent] = {}
1943
 
        parser[parent]['file'] = 'parent'
1944
 
        parser[child] = {}
1945
 
        parser[child]['file'] = 'child'
1946
 
        self.assertSectionNames([self.tree.basedir, parent], loc_config)
1947
 
 
1948
 
    def test_branch_data_default_section(self):
1949
 
        self.assertSectionNames([None],
1950
 
                                self.branch_config._get_branch_data_config())
1951
 
 
1952
 
    def test_branch_default_sections(self):
1953
 
        # No sections are defined in an empty locations file
1954
 
        self.assertSectionNames([None, 'DEFAULT'],
1955
 
                                self.branch_config)
1956
 
        # Unless we define an option
1957
 
        self.branch_config._get_location_config().set_user_option(
1958
 
            'file', 'locations')
1959
 
        self.assertSectionNames([self.tree.basedir, None, 'DEFAULT'],
1960
 
                                self.branch_config)
1961
 
 
1962
 
    def test_bazaar_named_section(self):
1963
 
        # We need to cheat as the API doesn't give direct access to sections
1964
 
        # other than DEFAULT.
1965
 
        self.bazaar_config.set_alias('bazaar', 'bzr')
1966
 
        self.assertSectionNames(['ALIASES'], self.bazaar_config, 'ALIASES')
1967
 
 
1968
 
 
1969
1474
class TestAuthenticationConfigFile(tests.TestCase):
1970
1475
    """Test the authentication.conf file matching"""
1971
1476
 
2466
1971
# test_user_prompted ?
2467
1972
class TestAuthenticationRing(tests.TestCaseWithTransport):
2468
1973
    pass
2469
 
 
2470
 
 
2471
 
class TestAutoUserId(tests.TestCase):
2472
 
    """Test inferring an automatic user name."""
2473
 
 
2474
 
    def test_auto_user_id(self):
2475
 
        """Automatic inference of user name.
2476
 
        
2477
 
        This is a bit hard to test in an isolated way, because it depends on
2478
 
        system functions that go direct to /etc or perhaps somewhere else.
2479
 
        But it's reasonable to say that on Unix, with an /etc/mailname, we ought
2480
 
        to be able to choose a user name with no configuration.
2481
 
        """
2482
 
        if sys.platform == 'win32':
2483
 
            raise TestSkipped("User name inference not implemented on win32")
2484
 
        realname, address = config._auto_user_id()
2485
 
        if os.path.exists('/etc/mailname'):
2486
 
            self.assertIsNot(None, realname)
2487
 
            self.assertIsNot(None, address)
2488
 
        else:
2489
 
            self.assertEquals((None, None), (realname, address))
2490