~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: 2010-08-30 21:23:49 UTC
  • mto: This revision was merged to the branch mainline in revision 5398.
  • Revision ID: john@arbash-meinel.com-20100830212349-figt9yz2cic6hy68
Remove the 'false' invocation.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2008, 2009 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
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 (
25
26
    branch,
26
27
    bzrdir,
27
28
    config,
 
29
    diff,
28
30
    errors,
29
31
    osutils,
30
32
    mail_client,
34
36
    trace,
35
37
    transport,
36
38
    )
 
39
from bzrlib.tests import features
37
40
from bzrlib.util.configobj import configobj
38
41
 
39
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
 
40
67
sample_long_alias="log -r-15..-1 --line"
41
68
sample_config_text = u"""
42
69
[DEFAULT]
43
70
email=Erik B\u00e5gfors <erik@bagfors.nu>
44
71
editor=vim
 
72
change_editor=vimdiff -of @new_path @old_path
45
73
gpg_signing_command=gnome-gpg
46
74
log_format=short
47
75
user_global_option=something
127
155
        self._calls.append(('keys',))
128
156
        return []
129
157
 
 
158
    def reload(self):
 
159
        self._calls.append(('reload',))
 
160
 
130
161
    def write(self, arg):
131
162
        self._calls.append(('write',))
132
163
 
208
239
        self._calls.append('_get_signature_checking')
209
240
        return self._signatures
210
241
 
 
242
    def _get_change_editor(self):
 
243
        self._calls.append('_get_change_editor')
 
244
        return 'vimdiff -fo @new_path @old_path'
 
245
 
211
246
 
212
247
bool_config = """[DEFAULT]
213
248
active = true
314
349
        my_config = config.Config()
315
350
        self.assertEqual('long', my_config.log_format())
316
351
 
 
352
    def test_get_change_editor(self):
 
353
        my_config = InstrumentedConfig()
 
354
        change_editor = my_config.get_change_editor('old_tree', 'new_tree')
 
355
        self.assertEqual(['_get_change_editor'], my_config._calls)
 
356
        self.assertIs(diff.DiffFromTool, change_editor.__class__)
 
357
        self.assertEqual(['vimdiff', '-fo', '@new_path', '@old_path'],
 
358
                         change_editor.command_template)
 
359
 
317
360
 
318
361
class TestConfigPath(tests.TestCase):
319
362
 
320
363
    def setUp(self):
321
364
        super(TestConfigPath, self).setUp()
322
365
        os.environ['HOME'] = '/home/bogus'
 
366
        os.environ['XDG_CACHE_DIR'] = ''
323
367
        if sys.platform == 'win32':
324
368
            os.environ['BZR_HOME'] = \
325
369
                r'C:\Documents and Settings\bogus\Application Data'
335
379
        self.assertEqual(config.config_filename(),
336
380
                         self.bzr_home + '/bazaar.conf')
337
381
 
338
 
    def test_branches_config_filename(self):
339
 
        self.assertEqual(config.branches_config_filename(),
340
 
                         self.bzr_home + '/branches.conf')
341
 
 
342
382
    def test_locations_config_filename(self):
343
383
        self.assertEqual(config.locations_config_filename(),
344
384
                         self.bzr_home + '/locations.conf')
347
387
        self.assertEqual(config.authentication_config_filename(),
348
388
                         self.bzr_home + '/authentication.conf')
349
389
 
350
 
 
351
 
class TestIniConfig(tests.TestCase):
 
390
    def test_xdg_cache_dir(self):
 
391
        self.assertEqual(config.xdg_cache_dir(),
 
392
            '/home/bogus/.cache')
 
393
 
 
394
 
 
395
class TestIniConfig(tests.TestCaseInTempDir):
 
396
 
 
397
    def make_config_parser(self, s):
 
398
        conf = config.IniBasedConfig.from_string(s)
 
399
        return conf, conf._get_parser()
 
400
 
 
401
 
 
402
class TestIniConfigBuilding(TestIniConfig):
352
403
 
353
404
    def test_contructs(self):
354
 
        my_config = config.IniBasedConfig("nothing")
 
405
        my_config = config.IniBasedConfig()
355
406
 
356
407
    def test_from_fp(self):
357
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
358
 
        my_config = config.IniBasedConfig(None)
359
 
        self.failUnless(
360
 
            isinstance(my_config._get_parser(file=config_file),
361
 
                        configobj.ConfigObj))
 
408
        my_config = config.IniBasedConfig.from_string(sample_config_text)
 
409
        self.assertIsInstance(my_config._get_parser(), configobj.ConfigObj)
362
410
 
363
411
    def test_cached(self):
364
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
365
 
        my_config = config.IniBasedConfig(None)
366
 
        parser = my_config._get_parser(file=config_file)
 
412
        my_config = config.IniBasedConfig.from_string(sample_config_text)
 
413
        parser = my_config._get_parser()
367
414
        self.failUnless(my_config._get_parser() is parser)
368
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
 
 
602
 
 
603
class TestGetUserOptionAs(TestIniConfig):
 
604
 
369
605
    def test_get_user_option_as_bool(self):
370
 
        config_file = StringIO("""
 
606
        conf, parser = self.make_config_parser("""
371
607
a_true_bool = true
372
608
a_false_bool = 0
373
609
an_invalid_bool = maybe
374
 
a_list = hmm, who knows ? # This interpreted as a list !
375
 
""".encode('utf-8'))
376
 
        my_config = config.IniBasedConfig(None)
377
 
        parser = my_config._get_parser(file=config_file)
378
 
        get_option = my_config.get_user_option_as_bool
379
 
        self.assertEqual(True, get_option('a_true_bool'))
380
 
        self.assertEqual(False, get_option('a_false_bool'))
381
 
        self.assertIs(None, get_option('an_invalid_bool'))
382
 
        self.assertIs(None, get_option('not_defined_in_this_config'))
 
610
a_list = hmm, who knows ? # This is interpreted as a list !
 
611
""")
 
612
        get_bool = conf.get_user_option_as_bool
 
613
        self.assertEqual(True, get_bool('a_true_bool'))
 
614
        self.assertEqual(False, get_bool('a_false_bool'))
 
615
        warnings = []
 
616
        def warning(*args):
 
617
            warnings.append(args[0] % args[1:])
 
618
        self.overrideAttr(trace, 'warning', warning)
 
619
        msg = 'Value "%s" is not a boolean for "%s"'
 
620
        self.assertIs(None, get_bool('an_invalid_bool'))
 
621
        self.assertEquals(msg % ('maybe', 'an_invalid_bool'), warnings[0])
 
622
        warnings = []
 
623
        self.assertIs(None, get_bool('not_defined_in_this_config'))
 
624
        self.assertEquals([], warnings)
 
625
 
 
626
    def test_get_user_option_as_list(self):
 
627
        conf, parser = self.make_config_parser("""
 
628
a_list = a,b,c
 
629
length_1 = 1,
 
630
one_item = x
 
631
""")
 
632
        get_list = conf.get_user_option_as_list
 
633
        self.assertEqual(['a', 'b', 'c'], get_list('a_list'))
 
634
        self.assertEqual(['1'], get_list('length_1'))
 
635
        self.assertEqual('x', conf.get_user_option('one_item'))
 
636
        # automatically cast to list
 
637
        self.assertEqual(['x'], get_list('one_item'))
 
638
 
 
639
 
 
640
class TestSupressWarning(TestIniConfig):
 
641
 
 
642
    def make_warnings_config(self, s):
 
643
        conf, parser = self.make_config_parser(s)
 
644
        return conf.suppress_warning
 
645
 
 
646
    def test_suppress_warning_unknown(self):
 
647
        suppress_warning = self.make_warnings_config('')
 
648
        self.assertEqual(False, suppress_warning('unknown_warning'))
 
649
 
 
650
    def test_suppress_warning_known(self):
 
651
        suppress_warning = self.make_warnings_config('suppress_warnings=a,b')
 
652
        self.assertEqual(False, suppress_warning('c'))
 
653
        self.assertEqual(True, suppress_warning('a'))
 
654
        self.assertEqual(True, suppress_warning('b'))
 
655
 
383
656
 
384
657
class TestGetConfig(tests.TestCase):
385
658
 
438
711
        branch = self.make_branch('branch')
439
712
        self.assertEqual('branch', branch.nick)
440
713
 
441
 
        locations = config.locations_config_filename()
442
 
        config.ensure_config_dir_exists()
443
714
        local_url = urlutils.local_path_to_url('branch')
444
 
        open(locations, 'wb').write('[%s]\nnickname = foobar'
445
 
                                    % (local_url,))
 
715
        conf = config.LocationConfig.from_string(
 
716
            '[%s]\nnickname = foobar' % (local_url,),
 
717
            local_url, save=True)
446
718
        self.assertEqual('foobar', branch.nick)
447
719
 
448
720
    def test_config_local_path(self):
450
722
        branch = self.make_branch('branch')
451
723
        self.assertEqual('branch', branch.nick)
452
724
 
453
 
        locations = config.locations_config_filename()
454
 
        config.ensure_config_dir_exists()
455
 
        open(locations, 'wb').write('[%s/branch]\nnickname = barry'
456
 
                                    % (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)
457
729
        self.assertEqual('barry', branch.nick)
458
730
 
459
731
    def test_config_creates_local(self):
460
732
        """Creating a new entry in config uses a local path."""
461
733
        branch = self.make_branch('branch', format='knit')
462
734
        branch.set_push_location('http://foobar')
463
 
        locations = config.locations_config_filename()
464
735
        local_path = osutils.getcwd().encode('utf8')
465
736
        # Surprisingly ConfigObj doesn't create a trailing newline
466
 
        self.check_file_contents(locations,
 
737
        self.check_file_contents(config.locations_config_filename(),
467
738
                                 '[%s/branch]\n'
468
739
                                 'push_location = http://foobar\n'
469
740
                                 'push_location:policy = norecurse\n'
474
745
        self.assertEqual('!repo', b.get_config().get_nickname())
475
746
 
476
747
    def test_warn_if_masked(self):
477
 
        _warning = trace.warning
478
748
        warnings = []
479
749
        def warning(*args):
480
750
            warnings.append(args[0] % args[1:])
 
751
        self.overrideAttr(trace, 'warning', warning)
481
752
 
482
753
        def set_option(store, warn_masked=True):
483
754
            warnings[:] = []
489
760
            else:
490
761
                self.assertEqual(1, len(warnings))
491
762
                self.assertEqual(warning, warnings[0])
492
 
        trace.warning = warning
493
 
        try:
494
 
            branch = self.make_branch('.')
495
 
            conf = branch.get_config()
496
 
            set_option(config.STORE_GLOBAL)
497
 
            assertWarning(None)
498
 
            set_option(config.STORE_BRANCH)
499
 
            assertWarning(None)
500
 
            set_option(config.STORE_GLOBAL)
501
 
            assertWarning('Value "4" is masked by "3" from branch.conf')
502
 
            set_option(config.STORE_GLOBAL, warn_masked=False)
503
 
            assertWarning(None)
504
 
            set_option(config.STORE_LOCATION)
505
 
            assertWarning(None)
506
 
            set_option(config.STORE_BRANCH)
507
 
            assertWarning('Value "3" is masked by "0" from locations.conf')
508
 
            set_option(config.STORE_BRANCH, warn_masked=False)
509
 
            assertWarning(None)
510
 
        finally:
511
 
            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)
512
779
 
513
780
 
514
781
class TestGlobalConfigItems(tests.TestCase):
515
782
 
516
783
    def test_user_id(self):
517
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
518
 
        my_config = config.GlobalConfig()
519
 
        my_config._parser = my_config._get_parser(file=config_file)
 
784
        my_config = config.GlobalConfig.from_string(sample_config_text)
520
785
        self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
521
786
                         my_config._get_user_id())
522
787
 
523
788
    def test_absent_user_id(self):
524
 
        config_file = StringIO("")
525
789
        my_config = config.GlobalConfig()
526
 
        my_config._parser = my_config._get_parser(file=config_file)
527
790
        self.assertEqual(None, my_config._get_user_id())
528
791
 
529
792
    def test_configured_editor(self):
530
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
531
 
        my_config = config.GlobalConfig()
532
 
        my_config._parser = my_config._get_parser(file=config_file)
 
793
        my_config = config.GlobalConfig.from_string(sample_config_text)
533
794
        self.assertEqual("vim", my_config.get_editor())
534
795
 
535
796
    def test_signatures_always(self):
536
 
        config_file = StringIO(sample_always_signatures)
537
 
        my_config = config.GlobalConfig()
538
 
        my_config._parser = my_config._get_parser(file=config_file)
 
797
        my_config = config.GlobalConfig.from_string(sample_always_signatures)
539
798
        self.assertEqual(config.CHECK_NEVER,
540
799
                         my_config.signature_checking())
541
800
        self.assertEqual(config.SIGN_ALWAYS,
543
802
        self.assertEqual(True, my_config.signature_needed())
544
803
 
545
804
    def test_signatures_if_possible(self):
546
 
        config_file = StringIO(sample_maybe_signatures)
547
 
        my_config = config.GlobalConfig()
548
 
        my_config._parser = my_config._get_parser(file=config_file)
 
805
        my_config = config.GlobalConfig.from_string(sample_maybe_signatures)
549
806
        self.assertEqual(config.CHECK_NEVER,
550
807
                         my_config.signature_checking())
551
808
        self.assertEqual(config.SIGN_WHEN_REQUIRED,
553
810
        self.assertEqual(False, my_config.signature_needed())
554
811
 
555
812
    def test_signatures_ignore(self):
556
 
        config_file = StringIO(sample_ignore_signatures)
557
 
        my_config = config.GlobalConfig()
558
 
        my_config._parser = my_config._get_parser(file=config_file)
 
813
        my_config = config.GlobalConfig.from_string(sample_ignore_signatures)
559
814
        self.assertEqual(config.CHECK_ALWAYS,
560
815
                         my_config.signature_checking())
561
816
        self.assertEqual(config.SIGN_NEVER,
563
818
        self.assertEqual(False, my_config.signature_needed())
564
819
 
565
820
    def _get_sample_config(self):
566
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
567
 
        my_config = config.GlobalConfig()
568
 
        my_config._parser = my_config._get_parser(file=config_file)
 
821
        my_config = config.GlobalConfig.from_string(sample_config_text)
569
822
        return my_config
570
823
 
571
824
    def test_gpg_signing_command(self):
574
827
        self.assertEqual(False, my_config.signature_needed())
575
828
 
576
829
    def _get_empty_config(self):
577
 
        config_file = StringIO("")
578
830
        my_config = config.GlobalConfig()
579
 
        my_config._parser = my_config._get_parser(file=config_file)
580
831
        return my_config
581
832
 
582
833
    def test_gpg_signing_command_unset(self):
620
871
        my_config = self._get_sample_config()
621
872
        self.assertEqual(sample_long_alias, my_config.get_alias('ll'))
622
873
 
 
874
    def test_get_change_editor(self):
 
875
        my_config = self._get_sample_config()
 
876
        change_editor = my_config.get_change_editor('old', 'new')
 
877
        self.assertIs(diff.DiffFromTool, change_editor.__class__)
 
878
        self.assertEqual('vimdiff -of @new_path @old_path',
 
879
                         ' '.join(change_editor.command_template))
 
880
 
 
881
    def test_get_no_change_editor(self):
 
882
        my_config = self._get_empty_config()
 
883
        change_editor = my_config.get_change_editor('old', 'new')
 
884
        self.assertIs(None, change_editor)
 
885
 
623
886
 
624
887
class TestGlobalConfigSavingOptions(tests.TestCaseInTempDir):
625
888
 
665
928
        self.assertEqual(parser._calls,
666
929
                         [('__init__', config.locations_config_filename(),
667
930
                           'utf-8')])
668
 
        config.ensure_config_dir_exists()
669
 
        #os.mkdir(config.config_dir())
670
 
        f = file(config.branches_config_filename(), 'wb')
671
 
        f.write('')
672
 
        f.close()
673
 
        oldparserclass = config.ConfigObj
674
 
        config.ConfigObj = InstrumentedConfigObj
675
 
        try:
676
 
            my_config = config.LocationConfig('http://www.example.com')
677
 
            parser = my_config._get_parser()
678
 
        finally:
679
 
            config.ConfigObj = oldparserclass
680
931
 
681
932
    def test_get_global_config(self):
682
933
        my_config = config.BranchConfig(FakeBranch('http://example.com'))
911
1162
                         self.my_config.post_commit())
912
1163
 
913
1164
    def get_branch_config(self, location, global_config=None):
 
1165
        my_branch = FakeBranch(location)
914
1166
        if global_config is None:
915
 
            global_file = StringIO(sample_config_text.encode('utf-8'))
916
 
        else:
917
 
            global_file = StringIO(global_config.encode('utf-8'))
918
 
        branches_file = StringIO(sample_branches_text.encode('utf-8'))
919
 
        self.my_config = config.BranchConfig(FakeBranch(location))
920
 
        # Force location config to use specified file
921
 
        self.my_location_config = self.my_config._get_location_config()
922
 
        self.my_location_config._get_parser(branches_file)
923
 
        # Force global config to use specified file
924
 
        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()
925
1176
 
926
1177
    def test_set_user_setting_sets_and_saves(self):
927
1178
        self.get_branch_config('/a/c')
928
1179
        record = InstrumentedConfigObj("foo")
929
1180
        self.my_location_config._parser = record
930
1181
 
931
 
        real_mkdir = os.mkdir
932
 
        self.created = False
933
 
        def checked_mkdir(path, mode=0777):
934
 
            self.log('making directory: %s', path)
935
 
            real_mkdir(path, mode)
936
 
            self.created = True
937
 
 
938
 
        os.mkdir = checked_mkdir
939
 
        try:
940
 
            self.callDeprecated(['The recurse option is deprecated as of '
941
 
                                 '0.14.  The section "/a/c" has been '
942
 
                                 'converted to use policies.'],
943
 
                                self.my_config.set_user_option,
944
 
                                'foo', 'bar', store=config.STORE_LOCATION)
945
 
        finally:
946
 
            os.mkdir = real_mkdir
947
 
 
948
 
        self.failUnless(self.created, 'Failed to create ~/.bazaar')
949
 
        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'),
950
1189
                          ('__contains__', '/a/c/'),
951
1190
                          ('__setitem__', '/a/c', {}),
952
1191
                          ('__getitem__', '/a/c'),
995
1234
option = exact
996
1235
"""
997
1236
 
998
 
 
999
1237
class TestBranchConfigItems(tests.TestCaseInTempDir):
1000
1238
 
1001
1239
    def get_branch_config(self, global_config=None, location=None,
1002
1240
                          location_config=None, branch_data_config=None):
1003
 
        my_config = config.BranchConfig(FakeBranch(location))
 
1241
        my_branch = FakeBranch(location)
1004
1242
        if global_config is not None:
1005
 
            global_file = StringIO(global_config.encode('utf-8'))
1006
 
            my_config._get_global_config()._get_parser(global_file)
1007
 
        self.my_location_config = my_config._get_location_config()
 
1243
            my_global_config = config.GlobalConfig.from_string(global_config,
 
1244
                                                               save=True)
1008
1245
        if location_config is not None:
1009
 
            location_file = StringIO(location_config.encode('utf-8'))
1010
 
            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)
1011
1249
        if branch_data_config is not None:
1012
1250
            my_config.branch.control_files.files['branch.conf'] = \
1013
1251
                branch_data_config
1027
1265
                         my_config.username())
1028
1266
 
1029
1267
    def test_not_set_in_branch(self):
1030
 
        my_config = self.get_branch_config(sample_config_text)
 
1268
        my_config = self.get_branch_config(global_config=sample_config_text)
1031
1269
        self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
1032
1270
                         my_config._get_user_id())
1033
1271
        my_config.branch.control_files.files['email'] = "John"
1057
1295
 
1058
1296
    def test_gpg_signing_command(self):
1059
1297
        my_config = self.get_branch_config(
 
1298
            global_config=sample_config_text,
1060
1299
            # branch data cannot set gpg_signing_command
1061
1300
            branch_data_config="gpg_signing_command=pgp")
1062
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
1063
 
        my_config._get_global_config()._get_parser(config_file)
1064
1301
        self.assertEqual('gnome-gpg', my_config.gpg_signing_command())
1065
1302
 
1066
1303
    def test_get_user_option_global(self):
1067
 
        branch = FakeBranch()
1068
 
        my_config = config.BranchConfig(branch)
1069
 
        config_file = StringIO(sample_config_text.encode('utf-8'))
1070
 
        (my_config._get_global_config()._get_parser(config_file))
 
1304
        my_config = self.get_branch_config(global_config=sample_config_text)
1071
1305
        self.assertEqual('something',
1072
1306
                         my_config.get_user_option('user_global_option'))
1073
1307
 
1074
1308
    def test_post_commit_default(self):
1075
 
        branch = FakeBranch()
1076
 
        my_config = self.get_branch_config(sample_config_text, '/a/c',
1077
 
                                           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)
1078
1312
        self.assertEqual(my_config.branch.base, '/a/c')
1079
1313
        self.assertEqual('bzrlib.tests.test_config.post_commit',
1080
1314
                         my_config.post_commit())
1081
1315
        my_config.set_user_option('post_commit', 'rmtree_root')
1082
 
        # post-commit is ignored when bresent in branch data
 
1316
        # post-commit is ignored when present in branch data
1083
1317
        self.assertEqual('bzrlib.tests.test_config.post_commit',
1084
1318
                         my_config.post_commit())
1085
1319
        my_config.set_user_option('post_commit', 'rmtree_root',
1087
1321
        self.assertEqual('rmtree_root', my_config.post_commit())
1088
1322
 
1089
1323
    def test_config_precedence(self):
 
1324
        # FIXME: eager test, luckily no persitent config file makes it fail
 
1325
        # -- vila 20100716
1090
1326
        my_config = self.get_branch_config(global_config=precedence_global)
1091
1327
        self.assertEqual(my_config.get_user_option('option'), 'global')
1092
1328
        my_config = self.get_branch_config(global_config=precedence_global,
1093
 
                                      branch_data_config=precedence_branch)
 
1329
                                           branch_data_config=precedence_branch)
1094
1330
        self.assertEqual(my_config.get_user_option('option'), 'branch')
1095
 
        my_config = self.get_branch_config(global_config=precedence_global,
1096
 
                                      branch_data_config=precedence_branch,
1097
 
                                      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)
1098
1335
        self.assertEqual(my_config.get_user_option('option'), 'recurse')
1099
 
        my_config = self.get_branch_config(global_config=precedence_global,
1100
 
                                      branch_data_config=precedence_branch,
1101
 
                                      location_config=precedence_location,
1102
 
                                      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')
1103
1341
        self.assertEqual(my_config.get_user_option('option'), 'exact')
1104
1342
 
1105
1343
    def test_get_mail_client(self):
1569
1807
        self.assertEquals(entered_password,
1570
1808
                          conf.get_password('ssh', 'bar.org', user='jim'))
1571
1809
        self.assertContainsRe(
1572
 
            self._get_log(keep_log_file=True),
 
1810
            self.get_log(),
1573
1811
            'password ignored in section \[ssh with password\]')
1574
1812
 
1575
1813
    def test_ssh_without_password_doesnt_emit_warning(self):
1594
1832
        # No warning shoud be emitted since there is no password. We are only
1595
1833
        # providing "user".
1596
1834
        self.assertNotContainsRe(
1597
 
            self._get_log(keep_log_file=True),
 
1835
            self.get_log(),
1598
1836
            'password ignored in section \[ssh with password\]')
1599
1837
 
1600
1838
    def test_uses_fallback_stores(self):
1601
 
        self._old_cs_registry = config.credential_store_registry
1602
 
        def restore():
1603
 
            config.credential_store_registry = self._old_cs_registry
1604
 
        self.addCleanup(restore)
1605
 
        config.credential_store_registry = config.CredentialStoreRegistry()
 
1839
        self.overrideAttr(config, 'credential_store_registry',
 
1840
                          config.CredentialStoreRegistry())
1606
1841
        store = StubCredentialStore()
1607
1842
        store.add_credentials("http", "example.com", "joe", "secret")
1608
1843
        config.credential_store_registry.register("stub", store, fallback=True)