~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_config.py

Add bzrlib.pyutils, which has get_named_object, a wrapper around __import__.

This is used to replace various ad hoc implementations of the same logic,
notably the version used in registry's _LazyObjectGetter which had a bug when
getting a module without also getting a member.  And of course, this new
function has unit tests, unlike the replaced code.

This also adds a KnownHooksRegistry subclass to provide a more natural home for
some other logic.

I'm not thrilled about the name of the new module or the new functions, but it's
hard to think of good names for such generic functionality.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
from cStringIO import StringIO
20
20
import os
21
21
import sys
 
22
import threading
22
23
 
23
24
#import bzrlib specific imports here
24
25
from bzrlib import (
35
36
    trace,
36
37
    transport,
37
38
    )
 
39
from bzrlib.tests import features
38
40
from bzrlib.util.configobj import configobj
39
41
 
40
42
 
 
43
def lockable_config_scenarios():
 
44
    return [
 
45
        ('global',
 
46
         {'config_class': config.GlobalConfig,
 
47
          'config_args': [],
 
48
          'config_section': 'DEFAULT'}),
 
49
        ('locations',
 
50
         {'config_class': config.LocationConfig,
 
51
          'config_args': ['.'],
 
52
          'config_section': '.'}),]
 
53
 
 
54
 
 
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
 
65
 
 
66
 
41
67
sample_long_alias="log -r-15..-1 --line"
42
68
sample_config_text = u"""
43
69
[DEFAULT]
129
155
        self._calls.append(('keys',))
130
156
        return []
131
157
 
 
158
    def reload(self):
 
159
        self._calls.append(('reload',))
 
160
 
132
161
    def write(self, arg):
133
162
        self._calls.append(('write',))
134
163
 
350
379
        self.assertEqual(config.config_filename(),
351
380
                         self.bzr_home + '/bazaar.conf')
352
381
 
353
 
    def test_branches_config_filename(self):
354
 
        self.assertEqual(config.branches_config_filename(),
355
 
                         self.bzr_home + '/branches.conf')
356
 
 
357
382
    def test_locations_config_filename(self):
358
383
        self.assertEqual(config.locations_config_filename(),
359
384
                         self.bzr_home + '/locations.conf')
367
392
            '/home/bogus/.cache')
368
393
 
369
394
 
370
 
class TestIniConfig(tests.TestCase):
 
395
class TestIniConfig(tests.TestCaseInTempDir):
371
396
 
372
397
    def make_config_parser(self, s):
373
 
        conf = config.IniBasedConfig(None)
374
 
        parser = conf._get_parser(file=StringIO(s.encode('utf-8')))
375
 
        return conf, parser
 
398
        conf = config.IniBasedConfig.from_string(s)
 
399
        return conf, conf._get_parser()
376
400
 
377
401
 
378
402
class TestIniConfigBuilding(TestIniConfig):
379
403
 
380
404
    def test_contructs(self):
381
 
        my_config = config.IniBasedConfig("nothing")
 
405
        my_config = config.IniBasedConfig()
382
406
 
383
407
    def test_from_fp(self):
384
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
385
 
        my_config = config.IniBasedConfig(None)
386
 
        self.failUnless(
387
 
            isinstance(my_config._get_parser(file=config_file),
388
 
                        configobj.ConfigObj))
 
408
        my_config = config.IniBasedConfig.from_string(sample_config_text)
 
409
        self.assertIsInstance(my_config._get_parser(), configobj.ConfigObj)
389
410
 
390
411
    def test_cached(self):
391
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
392
 
        my_config = config.IniBasedConfig(None)
393
 
        parser = my_config._get_parser(file=config_file)
 
412
        my_config = config.IniBasedConfig.from_string(sample_config_text)
 
413
        parser = my_config._get_parser()
394
414
        self.failUnless(my_config._get_parser() is parser)
395
415
 
 
416
    def _dummy_chown(self, path, uid, gid):
 
417
        self.path, self.uid, self.gid = path, uid, gid
 
418
 
 
419
    def test_ini_config_ownership(self):
 
420
        """Ensure that chown is happening during _write_config_file"""
 
421
        self.requireFeature(features.chown_feature)
 
422
        self.overrideAttr(os, 'chown', self._dummy_chown)
 
423
        self.path = self.uid = self.gid = None
 
424
        conf = config.IniBasedConfig(file_name='./foo.conf')
 
425
        conf._write_config_file()
 
426
        self.assertEquals(self.path, './foo.conf')
 
427
        self.assertTrue(isinstance(self.uid, int))
 
428
        self.assertTrue(isinstance(self.gid, int))
 
429
 
 
430
    def test_get_filename_parameter_is_deprecated_(self):
 
431
        conf = self.callDeprecated([
 
432
            'IniBasedConfig.__init__(get_filename) was deprecated in 2.3.'
 
433
            ' Use file_name instead.'],
 
434
            config.IniBasedConfig, lambda: 'ini.conf')
 
435
        self.assertEqual('ini.conf', conf.file_name)
 
436
 
 
437
    def test_get_parser_file_parameter_is_deprecated_(self):
 
438
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
439
        conf = config.IniBasedConfig.from_string(sample_config_text)
 
440
        conf = self.callDeprecated([
 
441
            'IniBasedConfig._get_parser(file=xxx) was deprecated in 2.3.'
 
442
            ' Use IniBasedConfig(_content=xxx) instead.'],
 
443
            conf._get_parser, file=config_file)
 
444
 
 
445
class TestIniConfigSaving(tests.TestCaseInTempDir):
 
446
 
 
447
    def test_cant_save_without_a_file_name(self):
 
448
        conf = config.IniBasedConfig()
 
449
        self.assertRaises(AssertionError, conf._write_config_file)
 
450
 
 
451
    def test_saved_with_content(self):
 
452
        content = 'foo = bar\n'
 
453
        conf = config.IniBasedConfig.from_string(
 
454
            content, file_name='./test.conf', save=True)
 
455
        self.assertFileEqual(content, 'test.conf')
 
456
 
 
457
 
 
458
class TestIniBaseConfigOnDisk(tests.TestCaseInTempDir):
 
459
 
 
460
    def test_cannot_reload_without_name(self):
 
461
        conf = config.IniBasedConfig.from_string(sample_config_text)
 
462
        self.assertRaises(AssertionError, conf.reload)
 
463
 
 
464
    def test_reload_see_new_value(self):
 
465
        c1 = config.IniBasedConfig.from_string('editor=vim\n',
 
466
                                               file_name='./test/conf')
 
467
        c1._write_config_file()
 
468
        c2 = config.IniBasedConfig.from_string('editor=emacs\n',
 
469
                                               file_name='./test/conf')
 
470
        c2._write_config_file()
 
471
        self.assertEqual('vim', c1.get_user_option('editor'))
 
472
        self.assertEqual('emacs', c2.get_user_option('editor'))
 
473
        # Make sure we get the Right value
 
474
        c1.reload()
 
475
        self.assertEqual('emacs', c1.get_user_option('editor'))
 
476
 
 
477
 
 
478
class TestLockableConfig(tests.TestCaseInTempDir):
 
479
 
 
480
    # Set by load_tests
 
481
    config_class = None
 
482
    config_args = None
 
483
    config_section = None
 
484
 
 
485
    def setUp(self):
 
486
        super(TestLockableConfig, self).setUp()
 
487
        self._content = '[%s]\none=1\ntwo=2\n' % (self.config_section,)
 
488
        self.config = self.create_config(self._content)
 
489
 
 
490
    def get_existing_config(self):
 
491
        return self.config_class(*self.config_args)
 
492
 
 
493
    def create_config(self, content):
 
494
        kwargs = dict(save=True)
 
495
        c = self.config_class.from_string(content, *self.config_args, **kwargs)
 
496
        return c
 
497
 
 
498
    def test_simple_read_access(self):
 
499
        self.assertEquals('1', self.config.get_user_option('one'))
 
500
 
 
501
    def test_simple_write_access(self):
 
502
        self.config.set_user_option('one', 'one')
 
503
        self.assertEquals('one', self.config.get_user_option('one'))
 
504
 
 
505
    def test_listen_to_the_last_speaker(self):
 
506
        c1 = self.config
 
507
        c2 = self.get_existing_config()
 
508
        c1.set_user_option('one', 'ONE')
 
509
        c2.set_user_option('two', 'TWO')
 
510
        self.assertEquals('ONE', c1.get_user_option('one'))
 
511
        self.assertEquals('TWO', c2.get_user_option('two'))
 
512
        # The second update respect the first one
 
513
        self.assertEquals('ONE', c2.get_user_option('one'))
 
514
 
 
515
    def test_last_speaker_wins(self):
 
516
        # If the same config is not shared, the same variable modified twice
 
517
        # can only see a single result.
 
518
        c1 = self.config
 
519
        c2 = self.get_existing_config()
 
520
        c1.set_user_option('one', 'c1')
 
521
        c2.set_user_option('one', 'c2')
 
522
        self.assertEquals('c2', c2._get_user_option('one'))
 
523
        # The first modification is still available until another refresh
 
524
        # occur
 
525
        self.assertEquals('c1', c1._get_user_option('one'))
 
526
        c1.set_user_option('two', 'done')
 
527
        self.assertEquals('c2', c1._get_user_option('one'))
 
528
 
 
529
    def test_writes_are_serialized(self):
 
530
        c1 = self.config
 
531
        c2 = self.get_existing_config()
 
532
 
 
533
        # We spawn a thread that will pause *during* the write
 
534
        before_writing = threading.Event()
 
535
        after_writing = threading.Event()
 
536
        writing_done = threading.Event()
 
537
        c1_orig = c1._write_config_file
 
538
        def c1_write_config_file():
 
539
            before_writing.set()
 
540
            c1_orig()
 
541
            # The lock is held we wait for the main thread to decide when to
 
542
            # continue
 
543
            after_writing.wait()
 
544
        c1._write_config_file = c1_write_config_file
 
545
        def c1_set_option():
 
546
            c1.set_user_option('one', 'c1')
 
547
            writing_done.set()
 
548
        t1 = threading.Thread(target=c1_set_option)
 
549
        # Collect the thread after the test
 
550
        self.addCleanup(t1.join)
 
551
        # Be ready to unblock the thread if the test goes wrong
 
552
        self.addCleanup(after_writing.set)
 
553
        t1.start()
 
554
        before_writing.wait()
 
555
        self.assertTrue(c1._lock.is_held)
 
556
        self.assertRaises(errors.LockContention,
 
557
                          c2.set_user_option, 'one', 'c2')
 
558
        self.assertEquals('c1', c1.get_user_option('one'))
 
559
        # Let the lock be released
 
560
        after_writing.set()
 
561
        writing_done.wait()
 
562
        c2.set_user_option('one', 'c2')
 
563
        self.assertEquals('c2', c2.get_user_option('one'))
 
564
 
 
565
    def test_read_while_writing(self):
 
566
       c1 = self.config
 
567
       # We spawn a thread that will pause *during* the write
 
568
       ready_to_write = threading.Event()
 
569
       do_writing = threading.Event()
 
570
       writing_done = threading.Event()
 
571
       c1_orig = c1._write_config_file
 
572
       def c1_write_config_file():
 
573
           ready_to_write.set()
 
574
           # The lock is held we wait for the main thread to decide when to
 
575
           # continue
 
576
           do_writing.wait()
 
577
           c1_orig()
 
578
           writing_done.set()
 
579
       c1._write_config_file = c1_write_config_file
 
580
       def c1_set_option():
 
581
           c1.set_user_option('one', 'c1')
 
582
       t1 = threading.Thread(target=c1_set_option)
 
583
       # Collect the thread after the test
 
584
       self.addCleanup(t1.join)
 
585
       # Be ready to unblock the thread if the test goes wrong
 
586
       self.addCleanup(do_writing.set)
 
587
       t1.start()
 
588
       # Ensure the thread is ready to write
 
589
       ready_to_write.wait()
 
590
       self.assertTrue(c1._lock.is_held)
 
591
       self.assertEquals('c1', c1.get_user_option('one'))
 
592
       # If we read during the write, we get the old value
 
593
       c2 = self.get_existing_config()
 
594
       self.assertEquals('1', c2.get_user_option('one'))
 
595
       # Let the writing occur and ensure it occurred
 
596
       do_writing.set()
 
597
       writing_done.wait()
 
598
       # Now we get the updated value
 
599
       c3 = self.get_existing_config()
 
600
       self.assertEquals('c1', c3.get_user_option('one'))
 
601
 
396
602
 
397
603
class TestGetUserOptionAs(TestIniConfig):
398
604
 
505
711
        branch = self.make_branch('branch')
506
712
        self.assertEqual('branch', branch.nick)
507
713
 
508
 
        locations = config.locations_config_filename()
509
 
        config.ensure_config_dir_exists()
510
714
        local_url = urlutils.local_path_to_url('branch')
511
 
        open(locations, 'wb').write('[%s]\nnickname = foobar'
512
 
                                    % (local_url,))
 
715
        conf = config.LocationConfig.from_string(
 
716
            '[%s]\nnickname = foobar' % (local_url,),
 
717
            local_url, save=True)
513
718
        self.assertEqual('foobar', branch.nick)
514
719
 
515
720
    def test_config_local_path(self):
517
722
        branch = self.make_branch('branch')
518
723
        self.assertEqual('branch', branch.nick)
519
724
 
520
 
        locations = config.locations_config_filename()
521
 
        config.ensure_config_dir_exists()
522
 
        open(locations, 'wb').write('[%s/branch]\nnickname = barry'
523
 
                                    % (osutils.getcwd().encode('utf8'),))
 
725
        local_path = osutils.getcwd().encode('utf8')
 
726
        conf = config.LocationConfig.from_string(
 
727
            '[%s/branch]\nnickname = barry' % (local_path,),
 
728
            'branch',  save=True)
524
729
        self.assertEqual('barry', branch.nick)
525
730
 
526
731
    def test_config_creates_local(self):
527
732
        """Creating a new entry in config uses a local path."""
528
733
        branch = self.make_branch('branch', format='knit')
529
734
        branch.set_push_location('http://foobar')
530
 
        locations = config.locations_config_filename()
531
735
        local_path = osutils.getcwd().encode('utf8')
532
736
        # Surprisingly ConfigObj doesn't create a trailing newline
533
 
        self.check_file_contents(locations,
 
737
        self.check_file_contents(config.locations_config_filename(),
534
738
                                 '[%s/branch]\n'
535
739
                                 'push_location = http://foobar\n'
536
740
                                 'push_location:policy = norecurse\n'
541
745
        self.assertEqual('!repo', b.get_config().get_nickname())
542
746
 
543
747
    def test_warn_if_masked(self):
544
 
        _warning = trace.warning
545
748
        warnings = []
546
749
        def warning(*args):
547
750
            warnings.append(args[0] % args[1:])
 
751
        self.overrideAttr(trace, 'warning', warning)
548
752
 
549
753
        def set_option(store, warn_masked=True):
550
754
            warnings[:] = []
556
760
            else:
557
761
                self.assertEqual(1, len(warnings))
558
762
                self.assertEqual(warning, warnings[0])
559
 
        trace.warning = warning
560
 
        try:
561
 
            branch = self.make_branch('.')
562
 
            conf = branch.get_config()
563
 
            set_option(config.STORE_GLOBAL)
564
 
            assertWarning(None)
565
 
            set_option(config.STORE_BRANCH)
566
 
            assertWarning(None)
567
 
            set_option(config.STORE_GLOBAL)
568
 
            assertWarning('Value "4" is masked by "3" from branch.conf')
569
 
            set_option(config.STORE_GLOBAL, warn_masked=False)
570
 
            assertWarning(None)
571
 
            set_option(config.STORE_LOCATION)
572
 
            assertWarning(None)
573
 
            set_option(config.STORE_BRANCH)
574
 
            assertWarning('Value "3" is masked by "0" from locations.conf')
575
 
            set_option(config.STORE_BRANCH, warn_masked=False)
576
 
            assertWarning(None)
577
 
        finally:
578
 
            trace.warning = _warning
 
763
        branch = self.make_branch('.')
 
764
        conf = branch.get_config()
 
765
        set_option(config.STORE_GLOBAL)
 
766
        assertWarning(None)
 
767
        set_option(config.STORE_BRANCH)
 
768
        assertWarning(None)
 
769
        set_option(config.STORE_GLOBAL)
 
770
        assertWarning('Value "4" is masked by "3" from branch.conf')
 
771
        set_option(config.STORE_GLOBAL, warn_masked=False)
 
772
        assertWarning(None)
 
773
        set_option(config.STORE_LOCATION)
 
774
        assertWarning(None)
 
775
        set_option(config.STORE_BRANCH)
 
776
        assertWarning('Value "3" is masked by "0" from locations.conf')
 
777
        set_option(config.STORE_BRANCH, warn_masked=False)
 
778
        assertWarning(None)
579
779
 
580
780
 
581
781
class TestGlobalConfigItems(tests.TestCase):
582
782
 
583
783
    def test_user_id(self):
584
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
585
 
        my_config = config.GlobalConfig()
586
 
        my_config._parser = my_config._get_parser(file=config_file)
 
784
        my_config = config.GlobalConfig.from_string(sample_config_text)
587
785
        self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
588
786
                         my_config._get_user_id())
589
787
 
590
788
    def test_absent_user_id(self):
591
 
        config_file = StringIO("")
592
789
        my_config = config.GlobalConfig()
593
 
        my_config._parser = my_config._get_parser(file=config_file)
594
790
        self.assertEqual(None, my_config._get_user_id())
595
791
 
596
792
    def test_configured_editor(self):
597
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
598
 
        my_config = config.GlobalConfig()
599
 
        my_config._parser = my_config._get_parser(file=config_file)
 
793
        my_config = config.GlobalConfig.from_string(sample_config_text)
600
794
        self.assertEqual("vim", my_config.get_editor())
601
795
 
602
796
    def test_signatures_always(self):
603
 
        config_file = StringIO(sample_always_signatures)
604
 
        my_config = config.GlobalConfig()
605
 
        my_config._parser = my_config._get_parser(file=config_file)
 
797
        my_config = config.GlobalConfig.from_string(sample_always_signatures)
606
798
        self.assertEqual(config.CHECK_NEVER,
607
799
                         my_config.signature_checking())
608
800
        self.assertEqual(config.SIGN_ALWAYS,
610
802
        self.assertEqual(True, my_config.signature_needed())
611
803
 
612
804
    def test_signatures_if_possible(self):
613
 
        config_file = StringIO(sample_maybe_signatures)
614
 
        my_config = config.GlobalConfig()
615
 
        my_config._parser = my_config._get_parser(file=config_file)
 
805
        my_config = config.GlobalConfig.from_string(sample_maybe_signatures)
616
806
        self.assertEqual(config.CHECK_NEVER,
617
807
                         my_config.signature_checking())
618
808
        self.assertEqual(config.SIGN_WHEN_REQUIRED,
620
810
        self.assertEqual(False, my_config.signature_needed())
621
811
 
622
812
    def test_signatures_ignore(self):
623
 
        config_file = StringIO(sample_ignore_signatures)
624
 
        my_config = config.GlobalConfig()
625
 
        my_config._parser = my_config._get_parser(file=config_file)
 
813
        my_config = config.GlobalConfig.from_string(sample_ignore_signatures)
626
814
        self.assertEqual(config.CHECK_ALWAYS,
627
815
                         my_config.signature_checking())
628
816
        self.assertEqual(config.SIGN_NEVER,
630
818
        self.assertEqual(False, my_config.signature_needed())
631
819
 
632
820
    def _get_sample_config(self):
633
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
634
 
        my_config = config.GlobalConfig()
635
 
        my_config._parser = my_config._get_parser(file=config_file)
 
821
        my_config = config.GlobalConfig.from_string(sample_config_text)
636
822
        return my_config
637
823
 
638
824
    def test_gpg_signing_command(self):
641
827
        self.assertEqual(False, my_config.signature_needed())
642
828
 
643
829
    def _get_empty_config(self):
644
 
        config_file = StringIO("")
645
830
        my_config = config.GlobalConfig()
646
 
        my_config._parser = my_config._get_parser(file=config_file)
647
831
        return my_config
648
832
 
649
833
    def test_gpg_signing_command_unset(self):
744
928
        self.assertEqual(parser._calls,
745
929
                         [('__init__', config.locations_config_filename(),
746
930
                           'utf-8')])
747
 
        config.ensure_config_dir_exists()
748
 
        #os.mkdir(config.config_dir())
749
 
        f = file(config.branches_config_filename(), 'wb')
750
 
        f.write('')
751
 
        f.close()
752
 
        oldparserclass = config.ConfigObj
753
 
        config.ConfigObj = InstrumentedConfigObj
754
 
        try:
755
 
            my_config = config.LocationConfig('http://www.example.com')
756
 
            parser = my_config._get_parser()
757
 
        finally:
758
 
            config.ConfigObj = oldparserclass
759
931
 
760
932
    def test_get_global_config(self):
761
933
        my_config = config.BranchConfig(FakeBranch('http://example.com'))
990
1162
                         self.my_config.post_commit())
991
1163
 
992
1164
    def get_branch_config(self, location, global_config=None):
 
1165
        my_branch = FakeBranch(location)
993
1166
        if global_config is None:
994
 
            global_file = StringIO(sample_config_text.encode('utf-8'))
995
 
        else:
996
 
            global_file = StringIO(global_config.encode('utf-8'))
997
 
        branches_file = StringIO(sample_branches_text.encode('utf-8'))
998
 
        self.my_config = config.BranchConfig(FakeBranch(location))
999
 
        # Force location config to use specified file
1000
 
        self.my_location_config = self.my_config._get_location_config()
1001
 
        self.my_location_config._get_parser(branches_file)
1002
 
        # Force global config to use specified file
1003
 
        self.my_config._get_global_config()._get_parser(global_file)
 
1167
            global_config = sample_config_text
 
1168
 
 
1169
        my_global_config = config.GlobalConfig.from_string(global_config,
 
1170
                                                           save=True)
 
1171
        my_location_config = config.LocationConfig.from_string(
 
1172
            sample_branches_text, my_branch.base, save=True)
 
1173
        my_config = config.BranchConfig(my_branch)
 
1174
        self.my_config = my_config
 
1175
        self.my_location_config = my_config._get_location_config()
1004
1176
 
1005
1177
    def test_set_user_setting_sets_and_saves(self):
1006
1178
        self.get_branch_config('/a/c')
1007
1179
        record = InstrumentedConfigObj("foo")
1008
1180
        self.my_location_config._parser = record
1009
1181
 
1010
 
        real_mkdir = os.mkdir
1011
 
        self.created = False
1012
 
        def checked_mkdir(path, mode=0777):
1013
 
            self.log('making directory: %s', path)
1014
 
            real_mkdir(path, mode)
1015
 
            self.created = True
1016
 
 
1017
 
        os.mkdir = checked_mkdir
1018
 
        try:
1019
 
            self.callDeprecated(['The recurse option is deprecated as of '
1020
 
                                 '0.14.  The section "/a/c" has been '
1021
 
                                 'converted to use policies.'],
1022
 
                                self.my_config.set_user_option,
1023
 
                                'foo', 'bar', store=config.STORE_LOCATION)
1024
 
        finally:
1025
 
            os.mkdir = real_mkdir
1026
 
 
1027
 
        self.failUnless(self.created, 'Failed to create ~/.bazaar')
1028
 
        self.assertEqual([('__contains__', '/a/c'),
 
1182
        self.callDeprecated(['The recurse option is deprecated as of '
 
1183
                             '0.14.  The section "/a/c" has been '
 
1184
                             'converted to use policies.'],
 
1185
                            self.my_config.set_user_option,
 
1186
                            'foo', 'bar', store=config.STORE_LOCATION)
 
1187
        self.assertEqual([('reload',),
 
1188
                          ('__contains__', '/a/c'),
1029
1189
                          ('__contains__', '/a/c/'),
1030
1190
                          ('__setitem__', '/a/c', {}),
1031
1191
                          ('__getitem__', '/a/c'),
1074
1234
option = exact
1075
1235
"""
1076
1236
 
1077
 
 
1078
1237
class TestBranchConfigItems(tests.TestCaseInTempDir):
1079
1238
 
1080
1239
    def get_branch_config(self, global_config=None, location=None,
1081
1240
                          location_config=None, branch_data_config=None):
1082
 
        my_config = config.BranchConfig(FakeBranch(location))
 
1241
        my_branch = FakeBranch(location)
1083
1242
        if global_config is not None:
1084
 
            global_file = StringIO(global_config.encode('utf-8'))
1085
 
            my_config._get_global_config()._get_parser(global_file)
1086
 
        self.my_location_config = my_config._get_location_config()
 
1243
            my_global_config = config.GlobalConfig.from_string(global_config,
 
1244
                                                               save=True)
1087
1245
        if location_config is not None:
1088
 
            location_file = StringIO(location_config.encode('utf-8'))
1089
 
            self.my_location_config._get_parser(location_file)
 
1246
            my_location_config = config.LocationConfig.from_string(
 
1247
                location_config, my_branch.base, save=True)
 
1248
        my_config = config.BranchConfig(my_branch)
1090
1249
        if branch_data_config is not None:
1091
1250
            my_config.branch.control_files.files['branch.conf'] = \
1092
1251
                branch_data_config
1106
1265
                         my_config.username())
1107
1266
 
1108
1267
    def test_not_set_in_branch(self):
1109
 
        my_config = self.get_branch_config(sample_config_text)
 
1268
        my_config = self.get_branch_config(global_config=sample_config_text)
1110
1269
        self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
1111
1270
                         my_config._get_user_id())
1112
1271
        my_config.branch.control_files.files['email'] = "John"
1136
1295
 
1137
1296
    def test_gpg_signing_command(self):
1138
1297
        my_config = self.get_branch_config(
 
1298
            global_config=sample_config_text,
1139
1299
            # branch data cannot set gpg_signing_command
1140
1300
            branch_data_config="gpg_signing_command=pgp")
1141
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
1142
 
        my_config._get_global_config()._get_parser(config_file)
1143
1301
        self.assertEqual('gnome-gpg', my_config.gpg_signing_command())
1144
1302
 
1145
1303
    def test_get_user_option_global(self):
1146
 
        branch = FakeBranch()
1147
 
        my_config = config.BranchConfig(branch)
1148
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
1149
 
        (my_config._get_global_config()._get_parser(config_file))
 
1304
        my_config = self.get_branch_config(global_config=sample_config_text)
1150
1305
        self.assertEqual('something',
1151
1306
                         my_config.get_user_option('user_global_option'))
1152
1307
 
1153
1308
    def test_post_commit_default(self):
1154
 
        branch = FakeBranch()
1155
 
        my_config = self.get_branch_config(sample_config_text, '/a/c',
1156
 
                                           sample_branches_text)
 
1309
        my_config = self.get_branch_config(global_config=sample_config_text,
 
1310
                                      location='/a/c',
 
1311
                                      location_config=sample_branches_text)
1157
1312
        self.assertEqual(my_config.branch.base, '/a/c')
1158
1313
        self.assertEqual('bzrlib.tests.test_config.post_commit',
1159
1314
                         my_config.post_commit())
1160
1315
        my_config.set_user_option('post_commit', 'rmtree_root')
1161
 
        # post-commit is ignored when bresent in branch data
 
1316
        # post-commit is ignored when present in branch data
1162
1317
        self.assertEqual('bzrlib.tests.test_config.post_commit',
1163
1318
                         my_config.post_commit())
1164
1319
        my_config.set_user_option('post_commit', 'rmtree_root',
1166
1321
        self.assertEqual('rmtree_root', my_config.post_commit())
1167
1322
 
1168
1323
    def test_config_precedence(self):
 
1324
        # FIXME: eager test, luckily no persitent config file makes it fail
 
1325
        # -- vila 20100716
1169
1326
        my_config = self.get_branch_config(global_config=precedence_global)
1170
1327
        self.assertEqual(my_config.get_user_option('option'), 'global')
1171
1328
        my_config = self.get_branch_config(global_config=precedence_global,
1172
 
                                      branch_data_config=precedence_branch)
 
1329
                                           branch_data_config=precedence_branch)
1173
1330
        self.assertEqual(my_config.get_user_option('option'), 'branch')
1174
 
        my_config = self.get_branch_config(global_config=precedence_global,
1175
 
                                      branch_data_config=precedence_branch,
1176
 
                                      location_config=precedence_location)
 
1331
        my_config = self.get_branch_config(
 
1332
            global_config=precedence_global,
 
1333
            branch_data_config=precedence_branch,
 
1334
            location_config=precedence_location)
1177
1335
        self.assertEqual(my_config.get_user_option('option'), 'recurse')
1178
 
        my_config = self.get_branch_config(global_config=precedence_global,
1179
 
                                      branch_data_config=precedence_branch,
1180
 
                                      location_config=precedence_location,
1181
 
                                      location='http://example.com/specific')
 
1336
        my_config = self.get_branch_config(
 
1337
            global_config=precedence_global,
 
1338
            branch_data_config=precedence_branch,
 
1339
            location_config=precedence_location,
 
1340
            location='http://example.com/specific')
1182
1341
        self.assertEqual(my_config.get_user_option('option'), 'exact')
1183
1342
 
1184
1343
    def test_get_mail_client(self):