~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_config.py

(jelmer) Update tests for no user identity being configured so they work
 when one can be inferred. (Martin Pool)

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
21
21
import sys
22
22
import threading
23
23
 
 
24
 
 
25
from testtools import matchers
 
26
 
24
27
#import bzrlib specific imports here
25
28
from bzrlib import (
26
29
    branch,
30
33
    errors,
31
34
    osutils,
32
35
    mail_client,
 
36
    mergetools,
33
37
    ui,
34
38
    urlutils,
35
39
    tests,
36
40
    trace,
37
41
    transport,
38
42
    )
39
 
from bzrlib.tests import features
 
43
from bzrlib.tests import (
 
44
    features,
 
45
    TestSkipped,
 
46
    scenarios,
 
47
    )
40
48
from bzrlib.util.configobj import configobj
41
49
 
42
50
 
52
60
          'config_section': '.'}),]
53
61
 
54
62
 
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
 
63
load_tests = scenarios.load_tests_apply_scenarios
65
64
 
66
65
 
67
66
sample_long_alias="log -r-15..-1 --line"
73
72
gpg_signing_command=gnome-gpg
74
73
log_format=short
75
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
76
78
[ALIASES]
77
79
h=help
78
80
ll=""" + sample_long_alias + "\n"
131
133
"""
132
134
 
133
135
 
 
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
 
134
179
class InstrumentedConfigObj(object):
135
180
    """A config obj look-enough-alike to record calls made to it."""
136
181
 
269
314
        """
270
315
        co = config.ConfigObj()
271
316
        co['test'] = 'foo#bar'
272
 
        lines = co.write()
 
317
        outfile = StringIO()
 
318
        co.write(outfile=outfile)
 
319
        lines = outfile.getvalue().splitlines()
273
320
        self.assertEqual(lines, ['test = "foo#bar"'])
274
321
        co2 = config.ConfigObj(lines)
275
322
        self.assertEqual(co2['test'], 'foo#bar')
276
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
 
277
348
 
278
349
erroneous_config = """[section] # line 1
279
350
good=good # line 2
362
433
 
363
434
    def setUp(self):
364
435
        super(TestConfigPath, self).setUp()
365
 
        os.environ['HOME'] = '/home/bogus'
366
 
        os.environ['XDG_CACHE_DIR'] = ''
 
436
        self.overrideEnv('HOME', '/home/bogus')
 
437
        self.overrideEnv('XDG_CACHE_DIR', '')
367
438
        if sys.platform == 'win32':
368
 
            os.environ['BZR_HOME'] = \
369
 
                r'C:\Documents and Settings\bogus\Application Data'
 
439
            self.overrideEnv(
 
440
                'BZR_HOME', r'C:\Documents and Settings\bogus\Application Data')
370
441
            self.bzr_home = \
371
442
                'C:/Documents and Settings/bogus/Application Data/bazaar/2.0'
372
443
        else:
392
463
            '/home/bogus/.cache')
393
464
 
394
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
 
395
494
class TestIniConfig(tests.TestCaseInTempDir):
396
495
 
397
496
    def make_config_parser(self, s):
442
541
            ' Use IniBasedConfig(_content=xxx) instead.'],
443
542
            conf._get_parser, file=config_file)
444
543
 
 
544
 
445
545
class TestIniConfigSaving(tests.TestCaseInTempDir):
446
546
 
447
547
    def test_cant_save_without_a_file_name(self):
455
555
        self.assertFileEqual(content, 'test.conf')
456
556
 
457
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
 
458
750
class TestIniBaseConfigOnDisk(tests.TestCaseInTempDir):
459
751
 
460
752
    def test_cannot_reload_without_name(self):
477
769
 
478
770
class TestLockableConfig(tests.TestCaseInTempDir):
479
771
 
 
772
    scenarios = lockable_config_scenarios()
 
773
 
480
774
    # Set by load_tests
481
775
    config_class = None
482
776
    config_args = None
883
1177
        change_editor = my_config.get_change_editor('old', 'new')
884
1178
        self.assertIs(None, change_editor)
885
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
 
886
1215
 
887
1216
class TestGlobalConfigSavingOptions(tests.TestCaseInTempDir):
888
1217
 
906
1235
        self.assertIs(None, new_config.get_alias('commit'))
907
1236
 
908
1237
 
909
 
class TestLocationConfig(tests.TestCaseInTempDir):
 
1238
class TestLocationConfig(tests.TestCaseInTempDir, TestOptionsMixin):
910
1239
 
911
1240
    def test_constructs(self):
912
1241
        my_config = config.LocationConfig('http://example.com')
1020
1349
            'http://www.example.com', 'appendpath_option'),
1021
1350
            config.POLICY_APPENDPATH)
1022
1351
 
 
1352
    def test__get_options_with_policy(self):
 
1353
        self.get_branch_config('/dir/subdir',
 
1354
                               location_config="""\
 
1355
[/dir]
 
1356
other_url = /other-dir
 
1357
other_url:policy = appendpath
 
1358
[/dir/subdir]
 
1359
other_url = /other-subdir
 
1360
""")
 
1361
        self.assertOptions(
 
1362
            [(u'other_url', u'/other-subdir', u'/dir/subdir', 'locations'),
 
1363
             (u'other_url', u'/other-dir', u'/dir', 'locations'),
 
1364
             (u'other_url:policy', u'appendpath', u'/dir', 'locations')],
 
1365
            self.my_location_config)
 
1366
 
1023
1367
    def test_location_without_username(self):
1024
1368
        self.get_branch_config('http://www.example.com/ignoreparent')
1025
1369
        self.assertEqual(u'Erik B\u00e5gfors <erik@bagfors.nu>',
1161
1505
        self.assertEqual('bzrlib.tests.test_config.post_commit',
1162
1506
                         self.my_config.post_commit())
1163
1507
 
1164
 
    def get_branch_config(self, location, global_config=None):
 
1508
    def get_branch_config(self, location, global_config=None,
 
1509
                          location_config=None):
1165
1510
        my_branch = FakeBranch(location)
1166
1511
        if global_config is None:
1167
1512
            global_config = sample_config_text
 
1513
        if location_config is None:
 
1514
            location_config = sample_branches_text
1168
1515
 
1169
1516
        my_global_config = config.GlobalConfig.from_string(global_config,
1170
1517
                                                           save=True)
1171
1518
        my_location_config = config.LocationConfig.from_string(
1172
 
            sample_branches_text, my_branch.base, save=True)
 
1519
            location_config, my_branch.base, save=True)
1173
1520
        my_config = config.BranchConfig(my_branch)
1174
1521
        self.my_config = my_config
1175
1522
        self.my_location_config = my_config._get_location_config()
1220
1567
        self.assertEqual('bzr', my_config.get_bzr_remote_path())
1221
1568
        my_config.set_user_option('bzr_remote_path', '/path-bzr')
1222
1569
        self.assertEqual('/path-bzr', my_config.get_bzr_remote_path())
1223
 
        os.environ['BZR_REMOTE_PATH'] = '/environ-bzr'
 
1570
        self.overrideEnv('BZR_REMOTE_PATH', '/environ-bzr')
1224
1571
        self.assertEqual('/environ-bzr', my_config.get_bzr_remote_path())
1225
1572
 
1226
1573
 
1272
1619
        self.assertEqual("John", my_config._get_user_id())
1273
1620
 
1274
1621
    def test_BZR_EMAIL_OVERRIDES(self):
1275
 
        os.environ['BZR_EMAIL'] = "Robert Collins <robertc@example.org>"
 
1622
        self.overrideEnv('BZR_EMAIL', "Robert Collins <robertc@example.org>")
1276
1623
        branch = FakeBranch()
1277
1624
        my_config = config.BranchConfig(branch)
1278
1625
        self.assertEqual("Robert Collins <robertc@example.org>",
1471
1818
        self.assertIs(None, bzrdir_config.get_default_stack_on())
1472
1819
 
1473
1820
 
1474
 
def create_configs(test):
1475
 
    """Create configuration files for a given test.
1476
 
 
1477
 
    This requires creating a tree (and populate the ``test.tree`` attribute and
1478
 
    its associated branch and will populate the following attributes:
1479
 
 
1480
 
    - branch_config: A BranchConfig for the associated branch.
1481
 
 
1482
 
    - locations_config : A LocationConfig for the associated branch
1483
 
 
1484
 
    - bazaar_config: A GlobalConfig.
1485
 
 
1486
 
    The tree and branch are created in a 'tree' subdirectory so the tests can
1487
 
    still use the test directory to stay outside of the branch.
1488
 
    """
1489
 
    tree = test.make_branch_and_tree('tree')
1490
 
    test.tree = tree
1491
 
    test.branch_config = config.BranchConfig(tree.branch)
1492
 
    test.locations_config = config.LocationConfig(tree.basedir)
1493
 
    test.bazaar_config = config.GlobalConfig()
1494
 
 
1495
 
 
1496
 
def create_configs_with_file_option(test):
1497
 
    """Create configuration files with a ``file`` option set in each.
1498
 
 
1499
 
    This builds on ``create_configs`` and add one ``file`` option in each
1500
 
    configuration with a value which allows identifying the configuration file.
1501
 
    """
1502
 
    create_configs(test)
1503
 
    test.bazaar_config.set_user_option('file', 'bazaar')
1504
 
    test.locations_config.set_user_option('file', 'locations')
1505
 
    test.branch_config.set_user_option('file', 'branch')
1506
 
 
1507
 
 
1508
 
class TestConfigGetOptions(tests.TestCaseWithTransport):
 
1821
class TestConfigGetOptions(tests.TestCaseWithTransport, TestOptionsMixin):
1509
1822
 
1510
1823
    def setUp(self):
1511
1824
        super(TestConfigGetOptions, self).setUp()
1512
1825
        create_configs(self)
1513
1826
 
1514
 
    def assertOptions(self, expected, conf):
1515
 
        actual = list(conf._get_options())
1516
 
        self.assertEqual(expected, actual)
1517
 
 
1518
1827
    # One variable in none of the above
1519
1828
    def test_no_variable(self):
1520
1829
        # Using branch should query branch, locations and bazaar
1563
1872
            self.branch_config)
1564
1873
 
1565
1874
 
1566
 
class TestConfigRemoveOption(tests.TestCaseWithTransport):
 
1875
class TestConfigRemoveOption(tests.TestCaseWithTransport, TestOptionsMixin):
1567
1876
 
1568
1877
    def setUp(self):
1569
1878
        super(TestConfigRemoveOption, self).setUp()
1570
1879
        create_configs_with_file_option(self)
1571
1880
 
1572
 
    def assertOptions(self, expected, conf):
1573
 
        actual = list(conf._get_options())
1574
 
        self.assertEqual(expected, actual)
1575
 
 
1576
1881
    def test_remove_in_locations(self):
1577
1882
        self.locations_config.remove_user_option('file', self.tree.basedir)
1578
1883
        self.assertOptions(
2165
2470
# test_user_prompted ?
2166
2471
class TestAuthenticationRing(tests.TestCaseWithTransport):
2167
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