~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_config.py

  • Committer: John Arbash Meinel
  • Date: 2011-04-07 10:36:24 UTC
  • mfrom: (5764 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5766.
  • Revision ID: john@arbash-meinel.com-20110407103624-n76g6tjeqmznwdcd
Merge bzr.dev 5764 to resolve release-notes (aka NEWS) conflicts

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005-2011 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
33
33
    errors,
34
34
    osutils,
35
35
    mail_client,
 
36
    mergetools,
36
37
    ui,
37
38
    urlutils,
38
39
    tests,
41
42
    )
42
43
from bzrlib.tests import (
43
44
    features,
 
45
    TestSkipped,
44
46
    scenarios,
45
47
    )
46
48
from bzrlib.util.configobj import configobj
70
72
gpg_signing_command=gnome-gpg
71
73
log_format=short
72
74
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
73
78
[ALIASES]
74
79
h=help
75
80
ll=""" + sample_long_alias + "\n"
309
314
        """
310
315
        co = config.ConfigObj()
311
316
        co['test'] = 'foo#bar'
312
 
        lines = co.write()
 
317
        outfile = StringIO()
 
318
        co.write(outfile=outfile)
 
319
        lines = outfile.getvalue().splitlines()
313
320
        self.assertEqual(lines, ['test = "foo#bar"'])
314
321
        co2 = config.ConfigObj(lines)
315
322
        self.assertEqual(co2['test'], 'foo#bar')
316
323
 
 
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
 
317
348
 
318
349
erroneous_config = """[section] # line 1
319
350
good=good # line 2
402
433
 
403
434
    def setUp(self):
404
435
        super(TestConfigPath, self).setUp()
405
 
        os.environ['HOME'] = '/home/bogus'
406
 
        os.environ['XDG_CACHE_DIR'] = ''
 
436
        self.overrideEnv('HOME', '/home/bogus')
 
437
        self.overrideEnv('XDG_CACHE_DIR', '')
407
438
        if sys.platform == 'win32':
408
 
            os.environ['BZR_HOME'] = \
409
 
                r'C:\Documents and Settings\bogus\Application Data'
 
439
            self.overrideEnv(
 
440
                'BZR_HOME', r'C:\Documents and Settings\bogus\Application Data')
410
441
            self.bzr_home = \
411
442
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0'
412
443
        else:
432
463
            '/home/bogus/.cache')
433
464
 
434
465
 
 
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
 
435
494
class TestIniConfig(tests.TestCaseInTempDir):
436
495
 
437
496
    def make_config_parser(self, s):
482
541
            ' Use IniBasedConfig(_content=xxx) instead.'],
483
542
            conf._get_parser, file=config_file)
484
543
 
 
544
 
485
545
class TestIniConfigSaving(tests.TestCaseInTempDir):
486
546
 
487
547
    def test_cant_save_without_a_file_name(self):
495
555
        self.assertFileEqual(content, 'test.conf')
496
556
 
497
557
 
 
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
 
498
750
class TestIniBaseConfigOnDisk(tests.TestCaseInTempDir):
499
751
 
500
752
    def test_cannot_reload_without_name(self):
925
1177
        change_editor = my_config.get_change_editor('old', 'new')
926
1178
        self.assertIs(None, change_editor)
927
1179
 
 
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
 
928
1215
 
929
1216
class TestGlobalConfigSavingOptions(tests.TestCaseInTempDir):
930
1217
 
1280
1567
        self.assertEqual('bzr', my_config.get_bzr_remote_path())
1281
1568
        my_config.set_user_option('bzr_remote_path', '/path-bzr')
1282
1569
        self.assertEqual('/path-bzr', my_config.get_bzr_remote_path())
1283
 
        os.environ['BZR_REMOTE_PATH'] = '/environ-bzr'
 
1570
        self.overrideEnv('BZR_REMOTE_PATH', '/environ-bzr')
1284
1571
        self.assertEqual('/environ-bzr', my_config.get_bzr_remote_path())
1285
1572
 
1286
1573
 
1332
1619
        self.assertEqual("John", my_config._get_user_id())
1333
1620
 
1334
1621
    def test_BZR_EMAIL_OVERRIDES(self):
1335
 
        os.environ['BZR_EMAIL'] = "Robert Collins <robertc@example.org>"
 
1622
        self.overrideEnv('BZR_EMAIL', "Robert Collins <robertc@example.org>")
1336
1623
        branch = FakeBranch()
1337
1624
        my_config = config.BranchConfig(branch)
1338
1625
        self.assertEqual("Robert Collins <robertc@example.org>",
2183
2470
# test_user_prompted ?
2184
2471
class TestAuthenticationRing(tests.TestCaseWithTransport):
2185
2472
    pass
 
2473
 
 
2474
 
 
2475
class TestAutoUserId(tests.TestCase):
 
2476
    """Test inferring an automatic user name."""
 
2477
 
 
2478
    def test_auto_user_id(self):
 
2479
        """Automatic inference of user name.
 
2480
        
 
2481
        This is a bit hard to test in an isolated way, because it depends on
 
2482
        system functions that go direct to /etc or perhaps somewhere else.
 
2483
        But it's reasonable to say that on Unix, with an /etc/mailname, we ought
 
2484
        to be able to choose a user name with no configuration.
 
2485
        """
 
2486
        if sys.platform == 'win32':
 
2487
            raise TestSkipped("User name inference not implemented on win32")
 
2488
        realname, address = config._auto_user_id()
 
2489
        if os.path.exists('/etc/mailname'):
 
2490
            self.assertTrue(realname)
 
2491
            self.assertTrue(address)
 
2492
        else:
 
2493
            self.assertEquals((None, None), (realname, address))
 
2494