~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_config.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-07-16 07:42:21 UTC
  • mfrom: (4466.1.4 spurious-stacking-warning)
  • Revision ID: pqm@pqm.ubuntu.com-20090716074221-a8ydf0c5tg54k35c
(andrew) Fix spurious 'does not support stacking' warning when
        pushing.

Show diffs side-by-side

added added

removed removed

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