~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: 2009-10-12 21:44:27 UTC
  • mto: This revision was merged to the branch mainline in revision 4737.
  • Revision ID: john@arbash-meinel.com-20091012214427-zddi1kmc2jlf7v31
Py_ssize_t and its associated function typedefs are not available w/ python 2.4

So we define them in python-compat.h
Even further, gcc issued a warning for:
static int
_workaround_pyrex_096()
So we changed it to:
_workaround_pyrex_096(void)

Also, some python api funcs were incorrectly defined as 'char *' when they meant
'const char *'. Work around that with a (char *) cast, to avoid compiler warnings.

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, 2009 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
23
22
 
24
23
#import bzrlib specific imports here
25
24
from bzrlib import (
26
25
    branch,
27
26
    bzrdir,
28
27
    config,
29
 
    diff,
30
28
    errors,
31
29
    osutils,
32
30
    mail_client,
36
34
    trace,
37
35
    transport,
38
36
    )
39
 
from bzrlib.tests import features
40
37
from bzrlib.util.configobj import configobj
41
38
 
42
39
 
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
40
sample_long_alias="log -r-15..-1 --line"
68
41
sample_config_text = u"""
69
42
[DEFAULT]
70
43
email=Erik B\u00e5gfors <erik@bagfors.nu>
71
44
editor=vim
72
 
change_editor=vimdiff -of @new_path @old_path
73
45
gpg_signing_command=gnome-gpg
74
46
log_format=short
75
47
user_global_option=something
155
127
        self._calls.append(('keys',))
156
128
        return []
157
129
 
158
 
    def reload(self):
159
 
        self._calls.append(('reload',))
160
 
 
161
130
    def write(self, arg):
162
131
        self._calls.append(('write',))
163
132
 
239
208
        self._calls.append('_get_signature_checking')
240
209
        return self._signatures
241
210
 
242
 
    def _get_change_editor(self):
243
 
        self._calls.append('_get_change_editor')
244
 
        return 'vimdiff -fo @new_path @old_path'
245
 
 
246
211
 
247
212
bool_config = """[DEFAULT]
248
213
active = true
349
314
        my_config = config.Config()
350
315
        self.assertEqual('long', my_config.log_format())
351
316
 
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
317
 
361
318
class TestConfigPath(tests.TestCase):
362
319
 
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')
392
353
            '/home/bogus/.cache')
393
354
 
394
355
 
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):
 
356
class TestIniConfig(tests.TestCase):
403
357
 
404
358
    def test_contructs(self):
405
 
        my_config = config.IniBasedConfig()
 
359
        my_config = config.IniBasedConfig("nothing")
406
360
 
407
361
    def test_from_fp(self):
408
 
        my_config = config.IniBasedConfig.from_string(sample_config_text)
409
 
        self.assertIsInstance(my_config._get_parser(), configobj.ConfigObj)
 
362
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
363
        my_config = config.IniBasedConfig(None)
 
364
        self.failUnless(
 
365
            isinstance(my_config._get_parser(file=config_file),
 
366
                        configobj.ConfigObj))
410
367
 
411
368
    def test_cached(self):
412
 
        my_config = config.IniBasedConfig.from_string(sample_config_text)
413
 
        parser = my_config._get_parser()
 
369
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
370
        my_config = config.IniBasedConfig(None)
 
371
        parser = my_config._get_parser(file=config_file)
414
372
        self.failUnless(my_config._get_parser() is parser)
415
373
 
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
374
    def test_get_user_option_as_bool(self):
606
 
        conf, parser = self.make_config_parser("""
 
375
        config_file = StringIO("""
607
376
a_true_bool = true
608
377
a_false_bool = 0
609
378
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
 
 
 
379
a_list = hmm, who knows ? # This interpreted as a list !
 
380
""".encode('utf-8'))
 
381
        my_config = config.IniBasedConfig(None)
 
382
        parser = my_config._get_parser(file=config_file)
 
383
        get_option = my_config.get_user_option_as_bool
 
384
        self.assertEqual(True, get_option('a_true_bool'))
 
385
        self.assertEqual(False, get_option('a_false_bool'))
 
386
        self.assertIs(None, get_option('an_invalid_bool'))
 
387
        self.assertIs(None, get_option('not_defined_in_this_config'))
656
388
 
657
389
class TestGetConfig(tests.TestCase):
658
390
 
711
443
        branch = self.make_branch('branch')
712
444
        self.assertEqual('branch', branch.nick)
713
445
 
 
446
        locations = config.locations_config_filename()
 
447
        config.ensure_config_dir_exists()
714
448
        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)
 
449
        open(locations, 'wb').write('[%s]\nnickname = foobar'
 
450
                                    % (local_url,))
718
451
        self.assertEqual('foobar', branch.nick)
719
452
 
720
453
    def test_config_local_path(self):
722
455
        branch = self.make_branch('branch')
723
456
        self.assertEqual('branch', branch.nick)
724
457
 
725
 
        local_path = osutils.getcwd().encode('utf8')
726
 
        conf = config.LocationConfig.from_string(
727
 
            '[%s/branch]\nnickname = barry' % (local_path,),
728
 
            'branch',  save=True)
 
458
        locations = config.locations_config_filename()
 
459
        config.ensure_config_dir_exists()
 
460
        open(locations, 'wb').write('[%s/branch]\nnickname = barry'
 
461
                                    % (osutils.getcwd().encode('utf8'),))
729
462
        self.assertEqual('barry', branch.nick)
730
463
 
731
464
    def test_config_creates_local(self):
732
465
        """Creating a new entry in config uses a local path."""
733
466
        branch = self.make_branch('branch', format='knit')
734
467
        branch.set_push_location('http://foobar')
 
468
        locations = config.locations_config_filename()
735
469
        local_path = osutils.getcwd().encode('utf8')
736
470
        # Surprisingly ConfigObj doesn't create a trailing newline
737
 
        self.check_file_contents(config.locations_config_filename(),
 
471
        self.check_file_contents(locations,
738
472
                                 '[%s/branch]\n'
739
473
                                 'push_location = http://foobar\n'
740
474
                                 'push_location:policy = norecurse\n'
745
479
        self.assertEqual('!repo', b.get_config().get_nickname())
746
480
 
747
481
    def test_warn_if_masked(self):
 
482
        _warning = trace.warning
748
483
        warnings = []
749
484
        def warning(*args):
750
485
            warnings.append(args[0] % args[1:])
751
 
        self.overrideAttr(trace, 'warning', warning)
752
486
 
753
487
        def set_option(store, warn_masked=True):
754
488
            warnings[:] = []
760
494
            else:
761
495
                self.assertEqual(1, len(warnings))
762
496
                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)
 
497
        trace.warning = warning
 
498
        try:
 
499
            branch = self.make_branch('.')
 
500
            conf = branch.get_config()
 
501
            set_option(config.STORE_GLOBAL)
 
502
            assertWarning(None)
 
503
            set_option(config.STORE_BRANCH)
 
504
            assertWarning(None)
 
505
            set_option(config.STORE_GLOBAL)
 
506
            assertWarning('Value "4" is masked by "3" from branch.conf')
 
507
            set_option(config.STORE_GLOBAL, warn_masked=False)
 
508
            assertWarning(None)
 
509
            set_option(config.STORE_LOCATION)
 
510
            assertWarning(None)
 
511
            set_option(config.STORE_BRANCH)
 
512
            assertWarning('Value "3" is masked by "0" from locations.conf')
 
513
            set_option(config.STORE_BRANCH, warn_masked=False)
 
514
            assertWarning(None)
 
515
        finally:
 
516
            trace.warning = _warning
779
517
 
780
518
 
781
519
class TestGlobalConfigItems(tests.TestCase):
782
520
 
783
521
    def test_user_id(self):
784
 
        my_config = config.GlobalConfig.from_string(sample_config_text)
 
522
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
523
        my_config = config.GlobalConfig()
 
524
        my_config._parser = my_config._get_parser(file=config_file)
785
525
        self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
786
526
                         my_config._get_user_id())
787
527
 
788
528
    def test_absent_user_id(self):
 
529
        config_file = StringIO("")
789
530
        my_config = config.GlobalConfig()
 
531
        my_config._parser = my_config._get_parser(file=config_file)
790
532
        self.assertEqual(None, my_config._get_user_id())
791
533
 
792
534
    def test_configured_editor(self):
793
 
        my_config = config.GlobalConfig.from_string(sample_config_text)
 
535
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
536
        my_config = config.GlobalConfig()
 
537
        my_config._parser = my_config._get_parser(file=config_file)
794
538
        self.assertEqual("vim", my_config.get_editor())
795
539
 
796
540
    def test_signatures_always(self):
797
 
        my_config = config.GlobalConfig.from_string(sample_always_signatures)
 
541
        config_file = StringIO(sample_always_signatures)
 
542
        my_config = config.GlobalConfig()
 
543
        my_config._parser = my_config._get_parser(file=config_file)
798
544
        self.assertEqual(config.CHECK_NEVER,
799
545
                         my_config.signature_checking())
800
546
        self.assertEqual(config.SIGN_ALWAYS,
802
548
        self.assertEqual(True, my_config.signature_needed())
803
549
 
804
550
    def test_signatures_if_possible(self):
805
 
        my_config = config.GlobalConfig.from_string(sample_maybe_signatures)
 
551
        config_file = StringIO(sample_maybe_signatures)
 
552
        my_config = config.GlobalConfig()
 
553
        my_config._parser = my_config._get_parser(file=config_file)
806
554
        self.assertEqual(config.CHECK_NEVER,
807
555
                         my_config.signature_checking())
808
556
        self.assertEqual(config.SIGN_WHEN_REQUIRED,
810
558
        self.assertEqual(False, my_config.signature_needed())
811
559
 
812
560
    def test_signatures_ignore(self):
813
 
        my_config = config.GlobalConfig.from_string(sample_ignore_signatures)
 
561
        config_file = StringIO(sample_ignore_signatures)
 
562
        my_config = config.GlobalConfig()
 
563
        my_config._parser = my_config._get_parser(file=config_file)
814
564
        self.assertEqual(config.CHECK_ALWAYS,
815
565
                         my_config.signature_checking())
816
566
        self.assertEqual(config.SIGN_NEVER,
818
568
        self.assertEqual(False, my_config.signature_needed())
819
569
 
820
570
    def _get_sample_config(self):
821
 
        my_config = config.GlobalConfig.from_string(sample_config_text)
 
571
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
572
        my_config = config.GlobalConfig()
 
573
        my_config._parser = my_config._get_parser(file=config_file)
822
574
        return my_config
823
575
 
824
576
    def test_gpg_signing_command(self):
827
579
        self.assertEqual(False, my_config.signature_needed())
828
580
 
829
581
    def _get_empty_config(self):
 
582
        config_file = StringIO("")
830
583
        my_config = config.GlobalConfig()
 
584
        my_config._parser = my_config._get_parser(file=config_file)
831
585
        return my_config
832
586
 
833
587
    def test_gpg_signing_command_unset(self):
871
625
        my_config = self._get_sample_config()
872
626
        self.assertEqual(sample_long_alias, my_config.get_alias('ll'))
873
627
 
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
628
 
887
629
class TestGlobalConfigSavingOptions(tests.TestCaseInTempDir):
888
630
 
928
670
        self.assertEqual(parser._calls,
929
671
                         [('__init__', config.locations_config_filename(),
930
672
                           'utf-8')])
 
673
        config.ensure_config_dir_exists()
 
674
        #os.mkdir(config.config_dir())
 
675
        f = file(config.branches_config_filename(), 'wb')
 
676
        f.write('')
 
677
        f.close()
 
678
        oldparserclass = config.ConfigObj
 
679
        config.ConfigObj = InstrumentedConfigObj
 
680
        try:
 
681
            my_config = config.LocationConfig('http://www.example.com')
 
682
            parser = my_config._get_parser()
 
683
        finally:
 
684
            config.ConfigObj = oldparserclass
931
685
 
932
686
    def test_get_global_config(self):
933
687
        my_config = config.BranchConfig(FakeBranch('http://example.com'))
1162
916
                         self.my_config.post_commit())
1163
917
 
1164
918
    def get_branch_config(self, location, global_config=None):
1165
 
        my_branch = FakeBranch(location)
1166
919
        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()
 
920
            global_file = StringIO(sample_config_text.encode('utf-8'))
 
921
        else:
 
922
            global_file = StringIO(global_config.encode('utf-8'))
 
923
        branches_file = StringIO(sample_branches_text.encode('utf-8'))
 
924
        self.my_config = config.BranchConfig(FakeBranch(location))
 
925
        # Force location config to use specified file
 
926
        self.my_location_config = self.my_config._get_location_config()
 
927
        self.my_location_config._get_parser(branches_file)
 
928
        # Force global config to use specified file
 
929
        self.my_config._get_global_config()._get_parser(global_file)
1176
930
 
1177
931
    def test_set_user_setting_sets_and_saves(self):
1178
932
        self.get_branch_config('/a/c')
1179
933
        record = InstrumentedConfigObj("foo")
1180
934
        self.my_location_config._parser = record
1181
935
 
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'),
 
936
        real_mkdir = os.mkdir
 
937
        self.created = False
 
938
        def checked_mkdir(path, mode=0777):
 
939
            self.log('making directory: %s', path)
 
940
            real_mkdir(path, mode)
 
941
            self.created = True
 
942
 
 
943
        os.mkdir = checked_mkdir
 
944
        try:
 
945
            self.callDeprecated(['The recurse option is deprecated as of '
 
946
                                 '0.14.  The section "/a/c" has been '
 
947
                                 'converted to use policies.'],
 
948
                                self.my_config.set_user_option,
 
949
                                'foo', 'bar', store=config.STORE_LOCATION)
 
950
        finally:
 
951
            os.mkdir = real_mkdir
 
952
 
 
953
        self.failUnless(self.created, 'Failed to create ~/.bazaar')
 
954
        self.assertEqual([('__contains__', '/a/c'),
1189
955
                          ('__contains__', '/a/c/'),
1190
956
                          ('__setitem__', '/a/c', {}),
1191
957
                          ('__getitem__', '/a/c'),
1234
1000
option = exact
1235
1001
"""
1236
1002
 
 
1003
 
1237
1004
class TestBranchConfigItems(tests.TestCaseInTempDir):
1238
1005
 
1239
1006
    def get_branch_config(self, global_config=None, location=None,
1240
1007
                          location_config=None, branch_data_config=None):
1241
 
        my_branch = FakeBranch(location)
 
1008
        my_config = config.BranchConfig(FakeBranch(location))
1242
1009
        if global_config is not None:
1243
 
            my_global_config = config.GlobalConfig.from_string(global_config,
1244
 
                                                               save=True)
 
1010
            global_file = StringIO(global_config.encode('utf-8'))
 
1011
            my_config._get_global_config()._get_parser(global_file)
 
1012
        self.my_location_config = my_config._get_location_config()
1245
1013
        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)
 
1014
            location_file = StringIO(location_config.encode('utf-8'))
 
1015
            self.my_location_config._get_parser(location_file)
1249
1016
        if branch_data_config is not None:
1250
1017
            my_config.branch.control_files.files['branch.conf'] = \
1251
1018
                branch_data_config
1265
1032
                         my_config.username())
1266
1033
 
1267
1034
    def test_not_set_in_branch(self):
1268
 
        my_config = self.get_branch_config(global_config=sample_config_text)
 
1035
        my_config = self.get_branch_config(sample_config_text)
1269
1036
        self.assertEqual(u"Erik B\u00e5gfors <erik@bagfors.nu>",
1270
1037
                         my_config._get_user_id())
1271
1038
        my_config.branch.control_files.files['email'] = "John"
1295
1062
 
1296
1063
    def test_gpg_signing_command(self):
1297
1064
        my_config = self.get_branch_config(
1298
 
            global_config=sample_config_text,
1299
1065
            # branch data cannot set gpg_signing_command
1300
1066
            branch_data_config="gpg_signing_command=pgp")
 
1067
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
1068
        my_config._get_global_config()._get_parser(config_file)
1301
1069
        self.assertEqual('gnome-gpg', my_config.gpg_signing_command())
1302
1070
 
1303
1071
    def test_get_user_option_global(self):
1304
 
        my_config = self.get_branch_config(global_config=sample_config_text)
 
1072
        branch = FakeBranch()
 
1073
        my_config = config.BranchConfig(branch)
 
1074
        config_file = StringIO(sample_config_text.encode('utf-8'))
 
1075
        (my_config._get_global_config()._get_parser(config_file))
1305
1076
        self.assertEqual('something',
1306
1077
                         my_config.get_user_option('user_global_option'))
1307
1078
 
1308
1079
    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)
 
1080
        branch = FakeBranch()
 
1081
        my_config = self.get_branch_config(sample_config_text, '/a/c',
 
1082
                                           sample_branches_text)
1312
1083
        self.assertEqual(my_config.branch.base, '/a/c')
1313
1084
        self.assertEqual('bzrlib.tests.test_config.post_commit',
1314
1085
                         my_config.post_commit())
1315
1086
        my_config.set_user_option('post_commit', 'rmtree_root')
1316
 
        # post-commit is ignored when present in branch data
 
1087
        # post-commit is ignored when bresent in branch data
1317
1088
        self.assertEqual('bzrlib.tests.test_config.post_commit',
1318
1089
                         my_config.post_commit())
1319
1090
        my_config.set_user_option('post_commit', 'rmtree_root',
1321
1092
        self.assertEqual('rmtree_root', my_config.post_commit())
1322
1093
 
1323
1094
    def test_config_precedence(self):
1324
 
        # FIXME: eager test, luckily no persitent config file makes it fail
1325
 
        # -- vila 20100716
1326
1095
        my_config = self.get_branch_config(global_config=precedence_global)
1327
1096
        self.assertEqual(my_config.get_user_option('option'), 'global')
1328
1097
        my_config = self.get_branch_config(global_config=precedence_global,
1329
 
                                           branch_data_config=precedence_branch)
 
1098
                                      branch_data_config=precedence_branch)
1330
1099
        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)
 
1100
        my_config = self.get_branch_config(global_config=precedence_global,
 
1101
                                      branch_data_config=precedence_branch,
 
1102
                                      location_config=precedence_location)
1335
1103
        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')
 
1104
        my_config = self.get_branch_config(global_config=precedence_global,
 
1105
                                      branch_data_config=precedence_branch,
 
1106
                                      location_config=precedence_location,
 
1107
                                      location='http://example.com/specific')
1341
1108
        self.assertEqual(my_config.get_user_option('option'), 'exact')
1342
1109
 
1343
1110
    def test_get_mail_client(self):
1807
1574
        self.assertEquals(entered_password,
1808
1575
                          conf.get_password('ssh', 'bar.org', user='jim'))
1809
1576
        self.assertContainsRe(
1810
 
            self.get_log(),
 
1577
            self._get_log(keep_log_file=True),
1811
1578
            'password ignored in section \[ssh with password\]')
1812
1579
 
1813
1580
    def test_ssh_without_password_doesnt_emit_warning(self):
1832
1599
        # No warning shoud be emitted since there is no password. We are only
1833
1600
        # providing "user".
1834
1601
        self.assertNotContainsRe(
1835
 
            self.get_log(),
 
1602
            self._get_log(keep_log_file=True),
1836
1603
            'password ignored in section \[ssh with password\]')
1837
1604
 
1838
1605
    def test_uses_fallback_stores(self):
1839
 
        self.overrideAttr(config, 'credential_store_registry',
1840
 
                          config.CredentialStoreRegistry())
 
1606
        self._old_cs_registry = config.credential_store_registry
 
1607
        def restore():
 
1608
            config.credential_store_registry = self._old_cs_registry
 
1609
        self.addCleanup(restore)
 
1610
        config.credential_store_registry = config.CredentialStoreRegistry()
1841
1611
        store = StubCredentialStore()
1842
1612
        store.add_credentials("http", "example.com", "joe", "secret")
1843
1613
        config.credential_store_registry.register("stub", store, fallback=True)