486
486
my_config.username())
487
487
self.assertEqual(['_get_user_id'], my_config._calls)
489
def test_signatures_default(self):
490
my_config = config.Config()
492
self.applyDeprecated(deprecated_in((2, 5, 0)),
493
my_config.signature_needed))
494
self.assertEqual(config.CHECK_IF_POSSIBLE,
495
self.applyDeprecated(deprecated_in((2, 5, 0)),
496
my_config.signature_checking))
497
self.assertEqual(config.SIGN_WHEN_REQUIRED,
498
self.applyDeprecated(deprecated_in((2, 5, 0)),
499
my_config.signing_policy))
501
def test_signatures_template_method(self):
502
my_config = InstrumentedConfig()
503
self.assertEqual(config.CHECK_NEVER,
504
self.applyDeprecated(deprecated_in((2, 5, 0)),
505
my_config.signature_checking))
506
self.assertEqual(['_get_signature_checking'], my_config._calls)
508
def test_signatures_template_method_none(self):
509
my_config = InstrumentedConfig()
510
my_config._signatures = None
511
self.assertEqual(config.CHECK_IF_POSSIBLE,
512
self.applyDeprecated(deprecated_in((2, 5, 0)),
513
my_config.signature_checking))
514
self.assertEqual(['_get_signature_checking'], my_config._calls)
516
def test_gpg_signing_command_default(self):
517
my_config = config.Config()
518
self.assertEqual('gpg',
519
self.applyDeprecated(deprecated_in((2, 5, 0)),
520
my_config.gpg_signing_command))
489
522
def test_get_user_option_default(self):
490
523
my_config = config.Config()
491
524
self.assertEqual(None, my_config.get_user_option('no_option'))
526
def test_post_commit_default(self):
527
my_config = config.Config()
528
self.assertEqual(None, self.applyDeprecated(deprecated_in((2, 5, 0)),
529
my_config.post_commit))
532
def test_log_format_default(self):
533
my_config = config.Config()
534
self.assertEqual('long',
535
self.applyDeprecated(deprecated_in((2, 5, 0)),
536
my_config.log_format))
538
def test_acceptable_keys_default(self):
539
my_config = config.Config()
540
self.assertEqual(None, self.applyDeprecated(deprecated_in((2, 5, 0)),
541
my_config.acceptable_keys))
493
543
def test_validate_signatures_in_log_default(self):
494
544
my_config = config.Config()
495
545
self.assertEqual(False, my_config.validate_signatures_in_log())
511
561
self.overrideEnv('XDG_CACHE_HOME', '')
512
562
if sys.platform == 'win32':
513
563
self.overrideEnv(
515
r'C:\Documents and Settings\bogus\Application Data')
517
'C:/Documents and Settings/bogus/Application Data/breezy'
564
'BZR_HOME', r'C:\Documents and Settings\bogus\Application Data')
566
'C:/Documents and Settings/bogus/Application Data/bazaar/2.0'
519
self.brz_home = '/home/bogus/.config/breezy'
521
def test_config_dir(self):
522
self.assertEqual(config.config_dir(), self.brz_home)
524
def test_config_dir_is_unicode(self):
525
self.assertIsInstance(config.config_dir(), unicode)
527
def test_config_filename(self):
528
self.assertEqual(config.config_filename(),
529
self.brz_home + '/breezy.conf')
531
def test_locations_config_filename(self):
532
self.assertEqual(config.locations_config_filename(),
533
self.brz_home + '/locations.conf')
535
def test_authentication_config_filename(self):
536
self.assertEqual(config.authentication_config_filename(),
537
self.brz_home + '/authentication.conf')
539
def test_xdg_cache_dir(self):
540
self.assertEqual(config.xdg_cache_dir(),
541
'/home/bogus/.cache')
544
class TestConfigPathFallback(tests.TestCaseInTempDir):
547
super(TestConfigPathFallback, self).setUp()
548
self.overrideEnv('HOME', self.test_dir)
549
self.overrideEnv('XDG_CACHE_HOME', '')
550
self.bzr_home = os.path.join(self.test_dir, '.bazaar')
551
os.mkdir(self.bzr_home)
568
self.bzr_home = '/home/bogus/.bazaar'
553
570
def test_config_dir(self):
554
571
self.assertEqual(config.config_dir(), self.bzr_home)
632
649
self.path = self.uid = self.gid = None
633
650
conf = config.IniBasedConfig(file_name='./foo.conf')
634
651
conf._write_config_file()
635
self.assertEqual(self.path, './foo.conf')
652
self.assertEquals(self.path, './foo.conf')
636
653
self.assertTrue(isinstance(self.uid, int))
637
654
self.assertTrue(isinstance(self.gid, int))
656
def test_get_filename_parameter_is_deprecated_(self):
657
conf = self.callDeprecated([
658
'IniBasedConfig.__init__(get_filename) was deprecated in 2.3.'
659
' Use file_name instead.'],
660
config.IniBasedConfig, lambda: 'ini.conf')
661
self.assertEqual('ini.conf', conf.file_name)
663
def test_get_parser_file_parameter_is_deprecated_(self):
664
config_file = StringIO(sample_config_text.encode('utf-8'))
665
conf = config.IniBasedConfig.from_string(sample_config_text)
666
conf = self.callDeprecated([
667
'IniBasedConfig._get_parser(file=xxx) was deprecated in 2.3.'
668
' Use IniBasedConfig(_content=xxx) instead.'],
669
conf._get_parser, file=config_file)
640
672
class TestIniConfigSaving(tests.TestCaseInTempDir):
707
739
def test_simple_loop(self):
708
740
c = self.get_config('foo={foo}')
709
self.assertRaises(config.OptionExpansionLoop, c.expand_options,
741
self.assertRaises(errors.OptionExpansionLoop, c.expand_options, '{foo}')
712
743
def test_indirect_loop(self):
713
744
c = self.get_config('''
717
e = self.assertRaises(config.OptionExpansionLoop,
748
e = self.assertRaises(errors.OptionExpansionLoop,
718
749
c.expand_options, '{foo}')
719
self.assertEqual('foo->bar->baz', e.refs)
720
self.assertEqual('{foo}', e.string)
750
self.assertEquals('foo->bar->baz', e.refs)
751
self.assertEquals('{foo}', e.string)
722
753
def test_list(self):
723
754
conf = self.get_config('''
773
804
[/another/branch/path]
776
self.assertRaises(config.ExpandingUnknownOption,
807
self.assertRaises(errors.ExpandingUnknownOption,
777
808
c.get_user_option, 'bar', expand=True)
779
810
def test_cross_related_sections(self):
780
c = self.get_config('/project/branch/path', '''
811
c = self.get_config('/project/branch/path','''
784
815
[/project/branch/path]
787
self.assertEqual('quux', c.get_user_option('bar', expand=True))
818
self.assertEquals('quux', c.get_user_option('bar', expand=True))
790
821
class TestIniBaseConfigOnDisk(tests.TestCaseInTempDir):
832
863
def test_simple_read_access(self):
833
self.assertEqual('1', self.config.get_user_option('one'))
864
self.assertEquals('1', self.config.get_user_option('one'))
835
866
def test_simple_write_access(self):
836
867
self.config.set_user_option('one', 'one')
837
self.assertEqual('one', self.config.get_user_option('one'))
868
self.assertEquals('one', self.config.get_user_option('one'))
839
870
def test_listen_to_the_last_speaker(self):
841
872
c2 = self.get_existing_config()
842
873
c1.set_user_option('one', 'ONE')
843
874
c2.set_user_option('two', 'TWO')
844
self.assertEqual('ONE', c1.get_user_option('one'))
845
self.assertEqual('TWO', c2.get_user_option('two'))
875
self.assertEquals('ONE', c1.get_user_option('one'))
876
self.assertEquals('TWO', c2.get_user_option('two'))
846
877
# The second update respect the first one
847
self.assertEqual('ONE', c2.get_user_option('one'))
878
self.assertEquals('ONE', c2.get_user_option('one'))
849
880
def test_last_speaker_wins(self):
850
881
# If the same config is not shared, the same variable modified twice
853
884
c2 = self.get_existing_config()
854
885
c1.set_user_option('one', 'c1')
855
886
c2.set_user_option('one', 'c2')
856
self.assertEqual('c2', c2._get_user_option('one'))
887
self.assertEquals('c2', c2._get_user_option('one'))
857
888
# The first modification is still available until another refresh
859
self.assertEqual('c1', c1._get_user_option('one'))
890
self.assertEquals('c1', c1._get_user_option('one'))
860
891
c1.set_user_option('two', 'done')
861
self.assertEqual('c2', c1._get_user_option('one'))
892
self.assertEquals('c2', c1._get_user_option('one'))
863
894
def test_writes_are_serialized(self):
889
920
self.assertTrue(c1._lock.is_held)
890
921
self.assertRaises(errors.LockContention,
891
922
c2.set_user_option, 'one', 'c2')
892
self.assertEqual('c1', c1.get_user_option('one'))
923
self.assertEquals('c1', c1.get_user_option('one'))
893
924
# Let the lock be released
894
925
after_writing.set()
895
926
writing_done.wait()
896
927
c2.set_user_option('one', 'c2')
897
self.assertEqual('c2', c2.get_user_option('one'))
928
self.assertEquals('c2', c2.get_user_option('one'))
899
930
def test_read_while_writing(self):
922
953
# Ensure the thread is ready to write
923
954
ready_to_write.wait()
924
955
self.assertTrue(c1._lock.is_held)
925
self.assertEqual('c1', c1.get_user_option('one'))
956
self.assertEquals('c1', c1.get_user_option('one'))
926
957
# If we read during the write, we get the old value
927
958
c2 = self.get_existing_config()
928
self.assertEqual('1', c2.get_user_option('one'))
959
self.assertEquals('1', c2.get_user_option('one'))
929
960
# Let the writing occur and ensure it occurred
931
962
writing_done.wait()
932
963
# Now we get the updated value
933
964
c3 = self.get_existing_config()
934
self.assertEqual('c1', c3.get_user_option('one'))
965
self.assertEquals('c1', c3.get_user_option('one'))
937
968
class TestGetUserOptionAs(TestIniConfig):
952
983
self.overrideAttr(trace, 'warning', warning)
953
984
msg = 'Value "%s" is not a boolean for "%s"'
954
985
self.assertIs(None, get_bool('an_invalid_bool'))
955
self.assertEqual(msg % ('maybe', 'an_invalid_bool'), warnings[0])
986
self.assertEquals(msg % ('maybe', 'an_invalid_bool'), warnings[0])
957
988
self.assertIs(None, get_bool('not_defined_in_this_config'))
958
self.assertEqual([], warnings)
989
self.assertEquals([], warnings)
960
991
def test_get_user_option_as_list(self):
961
992
conf, parser = self.make_config_parser("""
970
1001
# automatically cast to list
971
1002
self.assertEqual(['x'], get_list('one_item'))
1004
def test_get_user_option_as_int_from_SI(self):
1005
conf, parser = self.make_config_parser("""
1014
def get_si(s, default=None):
1015
return self.applyDeprecated(
1016
deprecated_in((2, 5, 0)),
1017
conf.get_user_option_as_int_from_SI, s, default)
1018
self.assertEqual(100, get_si('plain'))
1019
self.assertEqual(5000, get_si('si_k'))
1020
self.assertEqual(5000, get_si('si_kb'))
1021
self.assertEqual(5000000, get_si('si_m'))
1022
self.assertEqual(5000000, get_si('si_mb'))
1023
self.assertEqual(5000000000, get_si('si_g'))
1024
self.assertEqual(5000000000, get_si('si_gb'))
1025
self.assertEqual(None, get_si('non-exist'))
1026
self.assertEqual(42, get_si('non-exist-with-default', 42))
974
1029
class TestSupressWarning(TestIniConfig):
1140
1187
my_config = config.GlobalConfig()
1141
1188
self.assertEqual(None, my_config._get_user_id())
1190
def test_signatures_always(self):
1191
my_config = config.GlobalConfig.from_string(sample_always_signatures)
1192
self.assertEqual(config.CHECK_NEVER,
1193
self.applyDeprecated(deprecated_in((2, 5, 0)),
1194
my_config.signature_checking))
1195
self.assertEqual(config.SIGN_ALWAYS,
1196
self.applyDeprecated(deprecated_in((2, 5, 0)),
1197
my_config.signing_policy))
1198
self.assertEqual(True,
1199
self.applyDeprecated(deprecated_in((2, 5, 0)),
1200
my_config.signature_needed))
1202
def test_signatures_if_possible(self):
1203
my_config = config.GlobalConfig.from_string(sample_maybe_signatures)
1204
self.assertEqual(config.CHECK_NEVER,
1205
self.applyDeprecated(deprecated_in((2, 5, 0)),
1206
my_config.signature_checking))
1207
self.assertEqual(config.SIGN_WHEN_REQUIRED,
1208
self.applyDeprecated(deprecated_in((2, 5, 0)),
1209
my_config.signing_policy))
1210
self.assertEqual(False, self.applyDeprecated(deprecated_in((2, 5, 0)),
1211
my_config.signature_needed))
1213
def test_signatures_ignore(self):
1214
my_config = config.GlobalConfig.from_string(sample_ignore_signatures)
1215
self.assertEqual(config.CHECK_ALWAYS,
1216
self.applyDeprecated(deprecated_in((2, 5, 0)),
1217
my_config.signature_checking))
1218
self.assertEqual(config.SIGN_NEVER,
1219
self.applyDeprecated(deprecated_in((2, 5, 0)),
1220
my_config.signing_policy))
1221
self.assertEqual(False, self.applyDeprecated(deprecated_in((2, 5, 0)),
1222
my_config.signature_needed))
1224
def _get_sample_config(self):
1225
my_config = config.GlobalConfig.from_string(sample_config_text)
1228
def test_gpg_signing_command(self):
1229
my_config = self._get_sample_config()
1230
self.assertEqual("gnome-gpg",
1231
self.applyDeprecated(
1232
deprecated_in((2, 5, 0)), my_config.gpg_signing_command))
1233
self.assertEqual(False, self.applyDeprecated(deprecated_in((2, 5, 0)),
1234
my_config.signature_needed))
1236
def test_gpg_signing_key(self):
1237
my_config = self._get_sample_config()
1238
self.assertEqual("DD4D5088",
1239
self.applyDeprecated(deprecated_in((2, 5, 0)),
1240
my_config.gpg_signing_key))
1242
def _get_empty_config(self):
1243
my_config = config.GlobalConfig()
1246
def test_gpg_signing_command_unset(self):
1247
my_config = self._get_empty_config()
1248
self.assertEqual("gpg",
1249
self.applyDeprecated(
1250
deprecated_in((2, 5, 0)), my_config.gpg_signing_command))
1143
1252
def test_get_user_option_default(self):
1144
1253
my_config = self._get_empty_config()
1145
1254
self.assertEqual(None, my_config.get_user_option('no_option'))
1149
1258
self.assertEqual("something",
1150
1259
my_config.get_user_option('user_global_option'))
1261
def test_post_commit_default(self):
1262
my_config = self._get_sample_config()
1263
self.assertEqual(None,
1264
self.applyDeprecated(deprecated_in((2, 5, 0)),
1265
my_config.post_commit))
1267
def test_configured_logformat(self):
1268
my_config = self._get_sample_config()
1269
self.assertEqual("short",
1270
self.applyDeprecated(deprecated_in((2, 5, 0)),
1271
my_config.log_format))
1273
def test_configured_acceptable_keys(self):
1274
my_config = self._get_sample_config()
1275
self.assertEqual("amy",
1276
self.applyDeprecated(deprecated_in((2, 5, 0)),
1277
my_config.acceptable_keys))
1152
1279
def test_configured_validate_signatures_in_log(self):
1153
1280
my_config = self._get_sample_config()
1154
1281
self.assertEqual(True, my_config.validate_signatures_in_log())
1387
1514
self.assertEqual('Robert Collins <robertc@example.org>',
1388
1515
self.my_config.username())
1517
def test_signatures_not_set(self):
1518
self.get_branch_config('http://www.example.com',
1519
global_config=sample_ignore_signatures)
1520
self.assertEqual(config.CHECK_ALWAYS,
1521
self.applyDeprecated(deprecated_in((2, 5, 0)),
1522
self.my_config.signature_checking))
1523
self.assertEqual(config.SIGN_NEVER,
1524
self.applyDeprecated(deprecated_in((2, 5, 0)),
1525
self.my_config.signing_policy))
1527
def test_signatures_never(self):
1528
self.get_branch_config('/a/c')
1529
self.assertEqual(config.CHECK_NEVER,
1530
self.applyDeprecated(deprecated_in((2, 5, 0)),
1531
self.my_config.signature_checking))
1533
def test_signatures_when_available(self):
1534
self.get_branch_config('/a/', global_config=sample_ignore_signatures)
1535
self.assertEqual(config.CHECK_IF_POSSIBLE,
1536
self.applyDeprecated(deprecated_in((2, 5, 0)),
1537
self.my_config.signature_checking))
1539
def test_signatures_always(self):
1540
self.get_branch_config('/b')
1541
self.assertEqual(config.CHECK_ALWAYS,
1542
self.applyDeprecated(deprecated_in((2, 5, 0)),
1543
self.my_config.signature_checking))
1545
def test_gpg_signing_command(self):
1546
self.get_branch_config('/b')
1547
self.assertEqual("gnome-gpg",
1548
self.applyDeprecated(deprecated_in((2, 5, 0)),
1549
self.my_config.gpg_signing_command))
1551
def test_gpg_signing_command_missing(self):
1552
self.get_branch_config('/a')
1553
self.assertEqual("false",
1554
self.applyDeprecated(deprecated_in((2, 5, 0)),
1555
self.my_config.gpg_signing_command))
1557
def test_gpg_signing_key(self):
1558
self.get_branch_config('/b')
1559
self.assertEqual("DD4D5088", self.applyDeprecated(deprecated_in((2, 5, 0)),
1560
self.my_config.gpg_signing_key))
1562
def test_gpg_signing_key_default(self):
1563
self.get_branch_config('/a')
1564
self.assertEqual("erik@bagfors.nu",
1565
self.applyDeprecated(deprecated_in((2, 5, 0)),
1566
self.my_config.gpg_signing_key))
1390
1568
def test_get_user_option_global(self):
1391
1569
self.get_branch_config('/a')
1392
1570
self.assertEqual('something',
1456
1634
'http://www.example.com', 'norecurse_option'),
1457
1635
config.POLICY_NONE)
1637
def test_set_user_option_recurse_false_section(self):
1638
# The following section has recurse=False set. The test is to
1639
# make sure that a normal option can be added to the section,
1640
# converting recurse=False to the norecurse policy.
1641
self.get_branch_config('http://www.example.com/norecurse')
1642
self.callDeprecated(['The recurse option is deprecated as of 0.14. '
1643
'The section "http://www.example.com/norecurse" '
1644
'has been converted to use policies.'],
1645
self.my_config.set_user_option,
1646
'foo', 'bar', store=config.STORE_LOCATION)
1648
self.my_location_config._get_option_policy(
1649
'http://www.example.com/norecurse', 'foo'),
1651
# The previously existing option is still norecurse:
1653
self.my_location_config._get_option_policy(
1654
'http://www.example.com/norecurse', 'normal_option'),
1655
config.POLICY_NORECURSE)
1657
def test_post_commit_default(self):
1658
self.get_branch_config('/a/c')
1659
self.assertEqual('bzrlib.tests.test_config.post_commit',
1660
self.applyDeprecated(deprecated_in((2, 5, 0)),
1661
self.my_config.post_commit))
1459
1663
def get_branch_config(self, location, global_config=None,
1460
1664
location_config=None):
1461
1665
my_branch = FakeBranch(location)
1471
1675
self.my_config = my_config
1472
1676
self.my_location_config = my_config._get_location_config()
1678
def test_set_user_setting_sets_and_saves(self):
1679
self.get_branch_config('/a/c')
1680
record = InstrumentedConfigObj("foo")
1681
self.my_location_config._parser = record
1683
self.callDeprecated(['The recurse option is deprecated as of '
1684
'0.14. The section "/a/c" has been '
1685
'converted to use policies.'],
1686
self.my_config.set_user_option,
1687
'foo', 'bar', store=config.STORE_LOCATION)
1688
self.assertEqual([('reload',),
1689
('__contains__', '/a/c'),
1690
('__contains__', '/a/c/'),
1691
('__setitem__', '/a/c', {}),
1692
('__getitem__', '/a/c'),
1693
('__setitem__', 'foo', 'bar'),
1694
('__getitem__', '/a/c'),
1695
('as_bool', 'recurse'),
1696
('__getitem__', '/a/c'),
1697
('__delitem__', 'recurse'),
1698
('__getitem__', '/a/c'),
1700
('__getitem__', '/a/c'),
1701
('__contains__', 'foo:policy'),
1474
1705
def test_set_user_setting_sets_and_saves2(self):
1475
1706
self.get_branch_config('/a/c')
1476
1707
self.assertIs(self.my_config.get_user_option('foo'), None)
1530
1761
self.assertEqual("Robert Collins <robertc@example.org>",
1531
1762
my_config.username())
1533
def test_BRZ_EMAIL_OVERRIDES(self):
1534
self.overrideEnv('BRZ_EMAIL', "Robert Collins <robertc@example.org>")
1764
def test_BZR_EMAIL_OVERRIDES(self):
1765
self.overrideEnv('BZR_EMAIL', "Robert Collins <robertc@example.org>")
1535
1766
branch = FakeBranch()
1536
1767
my_config = config.BranchConfig(branch)
1537
1768
self.assertEqual("Robert Collins <robertc@example.org>",
1538
1769
my_config.username())
1771
def test_signatures_forced(self):
1772
my_config = self.get_branch_config(
1773
global_config=sample_always_signatures)
1774
self.assertEqual(config.CHECK_NEVER,
1775
self.applyDeprecated(deprecated_in((2, 5, 0)),
1776
my_config.signature_checking))
1777
self.assertEqual(config.SIGN_ALWAYS,
1778
self.applyDeprecated(deprecated_in((2, 5, 0)),
1779
my_config.signing_policy))
1780
self.assertTrue(self.applyDeprecated(deprecated_in((2, 5, 0)),
1781
my_config.signature_needed))
1783
def test_signatures_forced_branch(self):
1784
my_config = self.get_branch_config(
1785
global_config=sample_ignore_signatures,
1786
branch_data_config=sample_always_signatures)
1787
self.assertEqual(config.CHECK_NEVER,
1788
self.applyDeprecated(deprecated_in((2, 5, 0)),
1789
my_config.signature_checking))
1790
self.assertEqual(config.SIGN_ALWAYS,
1791
self.applyDeprecated(deprecated_in((2, 5, 0)),
1792
my_config.signing_policy))
1793
self.assertTrue(self.applyDeprecated(deprecated_in((2, 5, 0)),
1794
my_config.signature_needed))
1796
def test_gpg_signing_command(self):
1797
my_config = self.get_branch_config(
1798
global_config=sample_config_text,
1799
# branch data cannot set gpg_signing_command
1800
branch_data_config="gpg_signing_command=pgp")
1801
self.assertEqual('gnome-gpg',
1802
self.applyDeprecated(deprecated_in((2, 5, 0)),
1803
my_config.gpg_signing_command))
1540
1805
def test_get_user_option_global(self):
1541
1806
my_config = self.get_branch_config(global_config=sample_config_text)
1542
1807
self.assertEqual('something',
1543
1808
my_config.get_user_option('user_global_option'))
1810
def test_post_commit_default(self):
1811
my_config = self.get_branch_config(global_config=sample_config_text,
1813
location_config=sample_branches_text)
1814
self.assertEqual(my_config.branch.base, '/a/c')
1815
self.assertEqual('bzrlib.tests.test_config.post_commit',
1816
self.applyDeprecated(deprecated_in((2, 5, 0)),
1817
my_config.post_commit))
1818
my_config.set_user_option('post_commit', 'rmtree_root')
1819
# post-commit is ignored when present in branch data
1820
self.assertEqual('bzrlib.tests.test_config.post_commit',
1821
self.applyDeprecated(deprecated_in((2, 5, 0)),
1822
my_config.post_commit))
1823
my_config.set_user_option('post_commit', 'rmtree_root',
1824
store=config.STORE_LOCATION)
1825
self.assertEqual('rmtree_root',
1826
self.applyDeprecated(deprecated_in((2, 5, 0)),
1827
my_config.post_commit))
1545
1829
def test_config_precedence(self):
1546
1830
# FIXME: eager test, luckily no persitent config file makes it fail
1547
1831
# -- vila 20100716
1622
1906
# Store the raw content in the config file
1623
1907
t.put_bytes('foo.conf', utf8_content)
1624
1908
conf = config.TransportConfig(t, 'foo.conf')
1625
self.assertEqual(unicode_user, conf.get_option('user'))
1909
self.assertEquals(unicode_user, conf.get_option('user'))
1627
1911
def test_load_non_ascii(self):
1628
1912
"""Ensure we display a proper error on non-ascii, non utf-8 content."""
1629
1913
t = self.get_transport()
1630
1914
t.put_bytes('foo.conf', 'user=foo\n#\xff\n')
1631
1915
conf = config.TransportConfig(t, 'foo.conf')
1632
self.assertRaises(config.ConfigContentError, conf._get_configobj)
1916
self.assertRaises(errors.ConfigContentError, conf._get_configobj)
1634
1918
def test_load_erroneous_content(self):
1635
1919
"""Ensure we display a proper error on content that can't be parsed."""
1636
1920
t = self.get_transport()
1637
1921
t.put_bytes('foo.conf', '[open_section\n')
1638
1922
conf = config.TransportConfig(t, 'foo.conf')
1639
self.assertRaises(config.ParseConfigError, conf._get_configobj)
1923
self.assertRaises(errors.ParseConfigError, conf._get_configobj)
1641
1925
def test_load_permission_denied(self):
1642
1926
"""Ensure we get an empty config file if the file is inaccessible."""
1714
1998
config.OldConfigHooks.uninstall_named_hook, 'get', None)
1715
1999
self.assertLength(0, calls)
1716
2000
actual_value = conf.get_user_option(name)
1717
self.assertEqual(value, actual_value)
2001
self.assertEquals(value, actual_value)
1718
2002
self.assertLength(1, calls)
1719
self.assertEqual((conf, name, value), calls[0])
2003
self.assertEquals((conf, name, value), calls[0])
1721
def test_get_hook_breezy(self):
1722
self.assertGetHook(self.breezy_config, 'file', 'breezy')
2005
def test_get_hook_bazaar(self):
2006
self.assertGetHook(self.bazaar_config, 'file', 'bazaar')
1724
2008
def test_get_hook_locations(self):
1725
2009
self.assertGetHook(self.locations_config, 'file', 'locations')
1742
2026
# We can't assert the conf object below as different configs use
1743
2027
# different means to implement set_user_option and we care only about
1744
2028
# coverage here.
1745
self.assertEqual((name, value), calls[0][1:])
2029
self.assertEquals((name, value), calls[0][1:])
1747
def test_set_hook_breezy(self):
1748
self.assertSetHook(self.breezy_config, 'foo', 'breezy')
2031
def test_set_hook_bazaar(self):
2032
self.assertSetHook(self.bazaar_config, 'foo', 'bazaar')
1750
2034
def test_set_hook_locations(self):
1751
2035
self.assertSetHook(self.locations_config, 'foo', 'locations')
1766
2050
# We can't assert the conf object below as different configs use
1767
2051
# different means to implement remove_user_option and we care only about
1768
2052
# coverage here.
1769
self.assertEqual((name,), calls[0][1:])
2053
self.assertEquals((name,), calls[0][1:])
1771
def test_remove_hook_breezy(self):
1772
self.assertRemoveHook(self.breezy_config, 'file')
2055
def test_remove_hook_bazaar(self):
2056
self.assertRemoveHook(self.bazaar_config, 'file')
1774
2058
def test_remove_hook_locations(self):
1775
2059
self.assertRemoveHook(self.locations_config, 'file',
1845
2129
config.OldConfigHooks.uninstall_named_hook, 'get', None)
1846
2130
self.assertLength(0, calls)
1847
2131
actual_value = conf.get_option(name)
1848
self.assertEqual(value, actual_value)
2132
self.assertEquals(value, actual_value)
1849
2133
self.assertLength(1, calls)
1850
self.assertEqual((conf, name, value), calls[0])
2134
self.assertEquals((conf, name, value), calls[0])
1852
2136
def test_get_hook_remote_branch(self):
1853
2137
remote_branch = branch.Branch.open(self.get_url('tree'))
1989
2273
def test_default_value(self):
1990
2274
opt = config.Option('foo', default='bar')
1991
self.assertEqual('bar', opt.get_default())
2275
self.assertEquals('bar', opt.get_default())
1993
2277
def test_callable_default_value(self):
1994
2278
def bar_as_unicode():
1996
2280
opt = config.Option('foo', default=bar_as_unicode)
1997
self.assertEqual('bar', opt.get_default())
2281
self.assertEquals('bar', opt.get_default())
1999
2283
def test_default_value_from_env(self):
2000
2284
opt = config.Option('foo', default='bar', default_from_env=['FOO'])
2001
2285
self.overrideEnv('FOO', 'quux')
2002
2286
# Env variable provides a default taking over the option one
2003
self.assertEqual('quux', opt.get_default())
2287
self.assertEquals('quux', opt.get_default())
2005
2289
def test_first_default_value_from_env_wins(self):
2006
2290
opt = config.Option('foo', default='bar',
2026
2310
def test_get_help_topic(self):
2027
2311
opt = config.Option('foo')
2028
self.assertEqual('foo', opt.get_help_topic())
2312
self.assertEquals('foo', opt.get_help_topic())
2031
2315
class TestOptionConverter(tests.TestCase):
2033
2317
def assertConverted(self, expected, opt, value):
2034
self.assertEqual(expected, opt.convert_from_unicode(None, value))
2318
self.assertEquals(expected, opt.convert_from_unicode(None, value))
2036
2320
def assertCallsWarning(self, opt, value):
2039
2323
def warning(*args):
2040
2324
warnings.append(args[0] % args[1:])
2041
2325
self.overrideAttr(trace, 'warning', warning)
2042
self.assertEqual(None, opt.convert_from_unicode(None, value))
2326
self.assertEquals(None, opt.convert_from_unicode(None, value))
2043
2327
self.assertLength(1, warnings)
2045
2329
'Value "%s" is not valid for "%s"' % (value, opt.name),
2048
2332
def assertCallsError(self, opt, value):
2049
self.assertRaises(config.ConfigOptionValueError,
2333
self.assertRaises(errors.ConfigOptionValueError,
2050
2334
opt.convert_from_unicode, None, value)
2052
2336
def assertConvertInvalid(self, opt, invalid_value):
2053
2337
opt.invalid = None
2054
self.assertEqual(None, opt.convert_from_unicode(None, invalid_value))
2338
self.assertEquals(None, opt.convert_from_unicode(None, invalid_value))
2055
2339
opt.invalid = 'warning'
2056
2340
self.assertCallsWarning(opt, invalid_value)
2057
2341
opt.invalid = 'error'
2210
2494
def test_registered_help(self):
2211
2495
opt = config.Option('foo', help='A simple option')
2212
2496
self.registry.register(opt)
2213
self.assertEqual('A simple option', self.registry.get_help('foo'))
2497
self.assertEquals('A simple option', self.registry.get_help('foo'))
2215
2499
def test_dont_register_illegal_name(self):
2216
self.assertRaises(config.IllegalOptionName,
2500
self.assertRaises(errors.IllegalOptionName,
2217
2501
self.registry.register, config.Option(' foo'))
2218
self.assertRaises(config.IllegalOptionName,
2502
self.assertRaises(errors.IllegalOptionName,
2219
2503
self.registry.register, config.Option('bar,'))
2221
2505
lazy_option = config.Option('lazy_foo', help='Lazy help')
2236
2520
# the option name which indirectly requires that the option name is a
2237
2521
# valid python identifier. We violate that rule here (using a key that
2238
2522
# doesn't match the option name) to test the option name checking.
2239
self.assertRaises(config.IllegalOptionName,
2523
self.assertRaises(errors.IllegalOptionName,
2240
2524
self.registry.register_lazy, ' foo', self.__module__,
2241
2525
'TestOptionRegistry.lazy_option')
2242
self.assertRaises(config.IllegalOptionName,
2526
self.assertRaises(errors.IllegalOptionName,
2243
2527
self.registry.register_lazy, '1,2', self.__module__,
2244
2528
'TestOptionRegistry.lazy_option')
2257
2541
def test_proper_name(self):
2258
2542
# An option should be registered under its own name, this can't be
2259
2543
# checked at registration time for the lazy ones.
2260
self.assertEqual(self.option_name, self.option.name)
2544
self.assertEquals(self.option_name, self.option.name)
2262
2546
def test_help_is_set(self):
2263
2547
option_help = self.registry.get_help(self.option_name)
2264
2548
# Come on, think about the user, he really wants to know what the
2265
2549
# option is about
2266
2550
self.assertIsNot(None, option_help)
2267
self.assertNotEqual('', option_help)
2551
self.assertNotEquals('', option_help)
2270
2554
class TestSection(tests.TestCase):
2275
2559
def test_get_a_value(self):
2276
2560
a_dict = dict(foo='bar')
2277
2561
section = config.Section('myID', a_dict)
2278
self.assertEqual('bar', section.get('foo'))
2562
self.assertEquals('bar', section.get('foo'))
2280
2564
def test_get_unknown_option(self):
2281
2565
a_dict = dict()
2282
2566
section = config.Section(None, a_dict)
2283
self.assertEqual('out of thin air',
2567
self.assertEquals('out of thin air',
2284
2568
section.get('foo', 'out of thin air'))
2286
2570
def test_options_is_shared(self):
2300
2584
a_dict = dict(foo='bar')
2301
2585
section = self.get_section(a_dict)
2302
2586
section.set('foo', 'new_value')
2303
self.assertEqual('new_value', section.get('foo'))
2587
self.assertEquals('new_value', section.get('foo'))
2304
2588
# The change appears in the shared section
2305
self.assertEqual('new_value', a_dict.get('foo'))
2589
self.assertEquals('new_value', a_dict.get('foo'))
2306
2590
# We keep track of the change
2307
2591
self.assertTrue('foo' in section.orig)
2308
self.assertEqual('bar', section.orig.get('foo'))
2592
self.assertEquals('bar', section.orig.get('foo'))
2310
2594
def test_set_preserve_original_once(self):
2311
2595
a_dict = dict(foo='bar')
2314
2598
section.set('foo', 'second_value')
2315
2599
# We keep track of the original value
2316
2600
self.assertTrue('foo' in section.orig)
2317
self.assertEqual('bar', section.orig.get('foo'))
2601
self.assertEquals('bar', section.orig.get('foo'))
2319
2603
def test_remove(self):
2320
2604
a_dict = dict(foo='bar')
2321
2605
section = self.get_section(a_dict)
2322
2606
section.remove('foo')
2323
2607
# We get None for unknown options via the default value
2324
self.assertEqual(None, section.get('foo'))
2608
self.assertEquals(None, section.get('foo'))
2325
2609
# Or we just get the default value
2326
self.assertEqual('unknown', section.get('foo', 'unknown'))
2610
self.assertEquals('unknown', section.get('foo', 'unknown'))
2327
2611
self.assertFalse('foo' in section.options)
2328
2612
# We keep track of the deletion
2329
2613
self.assertTrue('foo' in section.orig)
2330
self.assertEqual('bar', section.orig.get('foo'))
2614
self.assertEquals('bar', section.orig.get('foo'))
2332
2616
def test_remove_new_option(self):
2333
2617
a_dict = dict()
2405
2689
class TestStore(tests.TestCaseWithTransport):
2407
def assertSectionContent(self, expected, store_and_section):
2691
def assertSectionContent(self, expected, (store, section)):
2408
2692
"""Assert that some options have the proper values in a section."""
2409
_, section = store_and_section
2410
2693
expected_name, expected_options = expected
2411
self.assertEqual(expected_name, section.id)
2694
self.assertEquals(expected_name, section.id)
2413
2696
expected_options,
2414
2697
dict([(k, section.get(k)) for k in expected_options.keys()]))
2422
2705
def test_building_delays_load(self):
2423
2706
store = self.get_store(self)
2424
self.assertEqual(False, store.is_loaded())
2707
self.assertEquals(False, store.is_loaded())
2425
2708
store._load_from_string('')
2426
self.assertEqual(True, store.is_loaded())
2709
self.assertEquals(True, store.is_loaded())
2428
2711
def test_get_no_sections_for_empty(self):
2429
2712
store = self.get_store(self)
2430
2713
store._load_from_string('')
2431
self.assertEqual([], list(store.get_sections()))
2714
self.assertEquals([], list(store.get_sections()))
2433
2716
def test_get_default_section(self):
2434
2717
store = self.get_store(self)
2514
2797
value = conf.get('a_section')
2515
2798
# Urgh, despite 'conf' asking for the no-name section, we get the
2516
2799
# content of another section as a dict o_O
2517
self.assertEqual({'a': '1'}, value)
2800
self.assertEquals({'a': '1'}, value)
2518
2801
unquoted = conf.store.unquote(value)
2519
2802
# Which cannot be unquoted but shouldn't crash either (the use cases
2520
2803
# are getting the value or displaying it. In the later case, '%s' will
2522
self.assertEqual({'a': '1'}, unquoted)
2523
self.assertEqual("{u'a': u'1'}", '%s' % (unquoted,))
2805
self.assertEquals({'a': '1'}, unquoted)
2806
self.assertEquals("{u'a': u'1'}", '%s' % (unquoted,))
2526
2809
class TestIniFileStoreContent(tests.TestCaseWithTransport):
2546
2829
store = config.TransportIniFileStore(t, 'foo.conf')
2548
2831
stack = config.Stack([store.get_sections], store)
2549
self.assertEqual(unicode_user, stack.get('user'))
2832
self.assertEquals(unicode_user, stack.get('user'))
2551
2834
def test_load_non_ascii(self):
2552
2835
"""Ensure we display a proper error on non-ascii, non utf-8 content."""
2553
2836
t = self.get_transport()
2554
2837
t.put_bytes('foo.conf', 'user=foo\n#%s\n' % (self.invalid_utf8_char,))
2555
2838
store = config.TransportIniFileStore(t, 'foo.conf')
2556
self.assertRaises(config.ConfigContentError, store.load)
2839
self.assertRaises(errors.ConfigContentError, store.load)
2558
2841
def test_load_erroneous_content(self):
2559
2842
"""Ensure we display a proper error on content that can't be parsed."""
2560
2843
t = self.get_transport()
2561
2844
t.put_bytes('foo.conf', '[open_section\n')
2562
2845
store = config.TransportIniFileStore(t, 'foo.conf')
2563
self.assertRaises(config.ParseConfigError, store.load)
2846
self.assertRaises(errors.ParseConfigError, store.load)
2565
2848
def test_load_permission_denied(self):
2566
2849
"""Ensure we get warned when trying to load an inaccessible file."""
2603
2886
with open('foo.conf', 'wb') as f:
2604
2887
f.write(utf8_content)
2605
2888
conf = config.IniBasedConfig(file_name='foo.conf')
2606
self.assertEqual(unicode_user, conf.get_user_option('user'))
2889
self.assertEquals(unicode_user, conf.get_user_option('user'))
2608
2891
def test_load_badly_encoded_content(self):
2609
2892
"""Ensure we display a proper error on non-ascii, non utf-8 content."""
2610
2893
with open('foo.conf', 'wb') as f:
2611
2894
f.write('user=foo\n#%s\n' % (self.invalid_utf8_char,))
2612
2895
conf = config.IniBasedConfig(file_name='foo.conf')
2613
self.assertRaises(config.ConfigContentError, conf._get_parser)
2896
self.assertRaises(errors.ConfigContentError, conf._get_parser)
2615
2898
def test_load_erroneous_content(self):
2616
2899
"""Ensure we display a proper error on content that can't be parsed."""
2617
2900
with open('foo.conf', 'wb') as f:
2618
2901
f.write('[open_section\n')
2619
2902
conf = config.IniBasedConfig(file_name='foo.conf')
2620
self.assertRaises(config.ParseConfigError, conf._get_parser)
2903
self.assertRaises(errors.ParseConfigError, conf._get_parser)
2623
2906
class TestMutableStore(TestStore):
2829
3112
s2.set('baz', 'quux')
2830
3113
s1.store.save()
2831
3114
# Changes don't propagate magically
2832
self.assertEqual(None, s1.get('baz'))
3115
self.assertEquals(None, s1.get('baz'))
2833
3116
s2.store.save_changes()
2834
self.assertEqual('quux', s2.get('baz'))
3117
self.assertEquals('quux', s2.get('baz'))
2835
3118
# Changes are acquired when saving
2836
self.assertEqual('bar', s2.get('foo'))
3119
self.assertEquals('bar', s2.get('foo'))
2837
3120
# Since there is no overlap, no warnings are emitted
2838
3121
self.assertLength(0, self.warnings)
2901
3184
def test_invalid_content(self):
2902
3185
store = config.TransportIniFileStore(self.get_transport(), 'foo.conf')
2903
self.assertEqual(False, store.is_loaded())
3186
self.assertEquals(False, store.is_loaded())
2904
3187
exc = self.assertRaises(
2905
config.ParseConfigError, store._load_from_string,
3188
errors.ParseConfigError, store._load_from_string,
2906
3189
'this is invalid !')
2907
3190
self.assertEndsWith(exc.filename, 'foo.conf')
2908
3191
# And the load failed
2909
self.assertEqual(False, store.is_loaded())
3192
self.assertEquals(False, store.is_loaded())
2911
3194
def test_get_embedded_sections(self):
2912
3195
# A more complicated example (which also shows that section names and
2979
3262
self.stack.store.save()
2981
3264
def test_simple_read_access(self):
2982
self.assertEqual('1', self.stack.get('one'))
3265
self.assertEquals('1', self.stack.get('one'))
2984
3267
def test_simple_write_access(self):
2985
3268
self.stack.set('one', 'one')
2986
self.assertEqual('one', self.stack.get('one'))
3269
self.assertEquals('one', self.stack.get('one'))
2988
3271
def test_listen_to_the_last_speaker(self):
2989
3272
c1 = self.stack
2990
3273
c2 = self.get_stack(self)
2991
3274
c1.set('one', 'ONE')
2992
3275
c2.set('two', 'TWO')
2993
self.assertEqual('ONE', c1.get('one'))
2994
self.assertEqual('TWO', c2.get('two'))
3276
self.assertEquals('ONE', c1.get('one'))
3277
self.assertEquals('TWO', c2.get('two'))
2995
3278
# The second update respect the first one
2996
self.assertEqual('ONE', c2.get('one'))
3279
self.assertEquals('ONE', c2.get('one'))
2998
3281
def test_last_speaker_wins(self):
2999
3282
# If the same config is not shared, the same variable modified twice
3071
3354
# Ensure the thread is ready to write
3072
3355
ready_to_write.wait()
3073
self.assertEqual('c1', c1.get('one'))
3356
self.assertEquals('c1', c1.get('one'))
3074
3357
# If we read during the write, we get the old value
3075
3358
c2 = self.get_stack(self)
3076
self.assertEqual('1', c2.get('one'))
3359
self.assertEquals('1', c2.get('one'))
3077
3360
# Let the writing occur and ensure it occurred
3078
3361
do_writing.set()
3079
3362
writing_done.wait()
3080
3363
# Now we get the updated value
3081
3364
c3 = self.get_stack(self)
3082
self.assertEqual('c1', c3.get('one'))
3365
self.assertEquals('c1', c3.get('one'))
3084
3367
# FIXME: It may be worth looking into removing the lock dir when it's not
3085
3368
# needed anymore and look at possible fallouts for concurrent lockers. This
3086
# will matter if/when we use config files outside of breezy directories
3087
# (.config/breezy or .bzr) -- vila 20110-04-111
3369
# will matter if/when we use config files outside of bazaar directories
3370
# (.bazaar or .bzr) -- vila 20110-04-111
3090
3373
class TestSectionMatcher(TestStore):
3118
3401
def test_simple_option(self):
3119
3402
section = self.get_section({'foo': 'bar'}, '')
3120
self.assertEqual('bar', section.get('foo'))
3403
self.assertEquals('bar', section.get('foo'))
3122
3405
def test_option_with_extra_path(self):
3123
3406
section = self.get_section({'foo': 'bar', 'foo:policy': 'appendpath'},
3125
self.assertEqual('bar/baz', section.get('foo'))
3408
self.assertEquals('bar/baz', section.get('foo'))
3127
3410
def test_invalid_policy(self):
3128
3411
section = self.get_section({'foo': 'bar', 'foo:policy': 'die'},
3130
3413
# invalid policies are ignored
3131
self.assertEqual('bar', section.get('foo'))
3414
self.assertEquals('bar', section.get('foo'))
3134
3417
class TestLocationMatcher(TestStore):
3153
3436
section=/quux/quux
3155
self.assertEqual(['/foo', '/foo/baz', '/foo/bar', '/foo/bar/baz',
3438
self.assertEquals(['/foo', '/foo/baz', '/foo/bar', '/foo/bar/baz',
3157
3440
[section.id for _, section in store.get_sections()])
3158
3441
matcher = config.LocationMatcher(store, '/foo/bar/quux')
3159
3442
sections = [section for _, section in matcher.get_sections()]
3160
self.assertEqual(['/foo/bar', '/foo'],
3443
self.assertEquals(['/foo/bar', '/foo'],
3161
3444
[section.id for section in sections])
3162
self.assertEqual(['quux', 'bar/quux'],
3445
self.assertEquals(['quux', 'bar/quux'],
3163
3446
[section.extra_path for section in sections])
3165
3448
def test_more_specific_sections_first(self):
3171
3454
section=/foo/bar
3173
self.assertEqual(['/foo', '/foo/bar'],
3456
self.assertEquals(['/foo', '/foo/bar'],
3174
3457
[section.id for _, section in store.get_sections()])
3175
3458
matcher = config.LocationMatcher(store, '/foo/bar/baz')
3176
3459
sections = [section for _, section in matcher.get_sections()]
3177
self.assertEqual(['/foo/bar', '/foo'],
3460
self.assertEquals(['/foo/bar', '/foo'],
3178
3461
[section.id for section in sections])
3179
self.assertEqual(['baz', 'bar/baz'],
3462
self.assertEquals(['baz', 'bar/baz'],
3180
3463
[section.extra_path for section in sections])
3182
3465
def test_appendpath_in_no_name_section(self):
3353
3636
store2 = config.IniFileStore()
3354
3637
store2._load_from_string('foo=baz')
3355
3638
conf = config.Stack([store1.get_sections, store2.get_sections])
3356
self.assertEqual('bar', conf.get('foo'))
3639
self.assertEquals('bar', conf.get('foo'))
3358
3641
def test_get_with_registered_default_value(self):
3359
3642
config.option_registry.register(config.Option('foo', default='bar'))
3360
3643
conf_stack = config.Stack([])
3361
self.assertEqual('bar', conf_stack.get('foo'))
3644
self.assertEquals('bar', conf_stack.get('foo'))
3363
3646
def test_get_without_registered_default_value(self):
3364
3647
config.option_registry.register(config.Option('foo'))
3365
3648
conf_stack = config.Stack([])
3366
self.assertEqual(None, conf_stack.get('foo'))
3649
self.assertEquals(None, conf_stack.get('foo'))
3368
3651
def test_get_without_default_value_for_not_registered(self):
3369
3652
conf_stack = config.Stack([])
3370
self.assertEqual(None, conf_stack.get('foo'))
3653
self.assertEquals(None, conf_stack.get('foo'))
3372
3655
def test_get_for_empty_section_callable(self):
3373
3656
conf_stack = config.Stack([lambda : []])
3374
self.assertEqual(None, conf_stack.get('foo'))
3657
self.assertEquals(None, conf_stack.get('foo'))
3376
3659
def test_get_for_broken_callable(self):
3377
3660
# Trying to use and invalid callable raises an exception on first use
3409
3692
self.overrideEnv('BAZ', 'baz')
3410
3693
# The first env var set wins
3411
3694
conf = self.get_conf('foo=store')
3412
self.assertEqual('foo', conf.get('foo'))
3695
self.assertEquals('foo', conf.get('foo'))
3415
3698
class TestMemoryStack(tests.TestCase):
3417
3700
def test_get(self):
3418
3701
conf = config.MemoryStack('foo=bar')
3419
self.assertEqual('bar', conf.get('foo'))
3702
self.assertEquals('bar', conf.get('foo'))
3421
3704
def test_set(self):
3422
3705
conf = config.MemoryStack('foo=bar')
3423
3706
conf.set('foo', 'baz')
3424
self.assertEqual('baz', conf.get('foo'))
3707
self.assertEquals('baz', conf.get('foo'))
3426
3709
def test_no_content(self):
3427
3710
conf = config.MemoryStack()
3498
3781
config.ConfigHooks.install_named_hook('get', hook, None)
3499
3782
self.assertLength(0, calls)
3500
3783
value = self.conf.get('foo')
3501
self.assertEqual('bar', value)
3784
self.assertEquals('bar', value)
3502
3785
self.assertLength(1, calls)
3503
self.assertEqual((self.conf, 'foo', 'bar'), calls[0])
3786
self.assertEquals((self.conf, 'foo', 'bar'), calls[0])
3506
3789
class TestStackGetWithConverter(tests.TestCase):
3522
3805
def test_get_default_bool_None(self):
3523
3806
self.register_bool_option('foo')
3524
3807
conf = self.get_conf('')
3525
self.assertEqual(None, conf.get('foo'))
3808
self.assertEquals(None, conf.get('foo'))
3527
3810
def test_get_default_bool_True(self):
3528
3811
self.register_bool_option('foo', u'True')
3529
3812
conf = self.get_conf('')
3530
self.assertEqual(True, conf.get('foo'))
3813
self.assertEquals(True, conf.get('foo'))
3532
3815
def test_get_default_bool_False(self):
3533
3816
self.register_bool_option('foo', False)
3534
3817
conf = self.get_conf('')
3535
self.assertEqual(False, conf.get('foo'))
3818
self.assertEquals(False, conf.get('foo'))
3537
3820
def test_get_default_bool_False_as_string(self):
3538
3821
self.register_bool_option('foo', u'False')
3539
3822
conf = self.get_conf('')
3540
self.assertEqual(False, conf.get('foo'))
3823
self.assertEquals(False, conf.get('foo'))
3542
3825
def test_get_default_bool_from_env_converted(self):
3543
3826
self.register_bool_option('foo', u'True', default_from_env=['FOO'])
3544
3827
self.overrideEnv('FOO', 'False')
3545
3828
conf = self.get_conf('')
3546
self.assertEqual(False, conf.get('foo'))
3829
self.assertEquals(False, conf.get('foo'))
3548
3831
def test_get_default_bool_when_conversion_fails(self):
3549
3832
self.register_bool_option('foo', default='True')
3550
3833
conf = self.get_conf('foo=invalid boolean')
3551
self.assertEqual(True, conf.get('foo'))
3834
self.assertEquals(True, conf.get('foo'))
3553
3836
def register_integer_option(self, name,
3554
3837
default=None, default_from_env=None):
3560
3843
def test_get_default_integer_None(self):
3561
3844
self.register_integer_option('foo')
3562
3845
conf = self.get_conf('')
3563
self.assertEqual(None, conf.get('foo'))
3846
self.assertEquals(None, conf.get('foo'))
3565
3848
def test_get_default_integer(self):
3566
3849
self.register_integer_option('foo', 42)
3567
3850
conf = self.get_conf('')
3568
self.assertEqual(42, conf.get('foo'))
3851
self.assertEquals(42, conf.get('foo'))
3570
3853
def test_get_default_integer_as_string(self):
3571
3854
self.register_integer_option('foo', u'42')
3572
3855
conf = self.get_conf('')
3573
self.assertEqual(42, conf.get('foo'))
3856
self.assertEquals(42, conf.get('foo'))
3575
3858
def test_get_default_integer_from_env(self):
3576
3859
self.register_integer_option('foo', default_from_env=['FOO'])
3577
3860
self.overrideEnv('FOO', '18')
3578
3861
conf = self.get_conf('')
3579
self.assertEqual(18, conf.get('foo'))
3862
self.assertEquals(18, conf.get('foo'))
3581
3864
def test_get_default_integer_when_conversion_fails(self):
3582
3865
self.register_integer_option('foo', default='12')
3583
3866
conf = self.get_conf('foo=invalid integer')
3584
self.assertEqual(12, conf.get('foo'))
3867
self.assertEquals(12, conf.get('foo'))
3586
3869
def register_list_option(self, name, default=None, default_from_env=None):
3587
3870
l = config.ListOption(name, help='A list.', default=default,
3591
3874
def test_get_default_list_None(self):
3592
3875
self.register_list_option('foo')
3593
3876
conf = self.get_conf('')
3594
self.assertEqual(None, conf.get('foo'))
3877
self.assertEquals(None, conf.get('foo'))
3596
3879
def test_get_default_list_empty(self):
3597
3880
self.register_list_option('foo', '')
3598
3881
conf = self.get_conf('')
3599
self.assertEqual([], conf.get('foo'))
3882
self.assertEquals([], conf.get('foo'))
3601
3884
def test_get_default_list_from_env(self):
3602
3885
self.register_list_option('foo', default_from_env=['FOO'])
3603
3886
self.overrideEnv('FOO', '')
3604
3887
conf = self.get_conf('')
3605
self.assertEqual([], conf.get('foo'))
3888
self.assertEquals([], conf.get('foo'))
3607
3890
def test_get_with_list_converter_no_item(self):
3608
3891
self.register_list_option('foo', None)
3609
3892
conf = self.get_conf('foo=,')
3610
self.assertEqual([], conf.get('foo'))
3893
self.assertEquals([], conf.get('foo'))
3612
3895
def test_get_with_list_converter_many_items(self):
3613
3896
self.register_list_option('foo', None)
3614
3897
conf = self.get_conf('foo=m,o,r,e')
3615
self.assertEqual(['m', 'o', 'r', 'e'], conf.get('foo'))
3898
self.assertEquals(['m', 'o', 'r', 'e'], conf.get('foo'))
3617
3900
def test_get_with_list_converter_embedded_spaces_many_items(self):
3618
3901
self.register_list_option('foo', None)
3619
3902
conf = self.get_conf('foo=" bar", "baz "')
3620
self.assertEqual([' bar', 'baz '], conf.get('foo'))
3903
self.assertEquals([' bar', 'baz '], conf.get('foo'))
3622
3905
def test_get_with_list_converter_stripped_spaces_many_items(self):
3623
3906
self.register_list_option('foo', None)
3624
3907
conf = self.get_conf('foo= bar , baz ')
3625
self.assertEqual(['bar', 'baz'], conf.get('foo'))
3908
self.assertEquals(['bar', 'baz'], conf.get('foo'))
3628
3911
class TestIterOptionRefs(tests.TestCase):
3629
3912
"""iter_option_refs is a bit unusual, document some cases."""
3631
3914
def assertRefs(self, expected, string):
3632
self.assertEqual(expected, list(config.iter_option_refs(string)))
3915
self.assertEquals(expected, list(config.iter_option_refs(string)))
3634
3917
def test_empty(self):
3635
3918
self.assertRefs([(False, '')], '')
3675
3958
def test_expand_default_value(self):
3676
3959
self.conf.store._load_from_string('bar=baz')
3677
3960
self.registry.register(config.Option('foo', default=u'{bar}'))
3678
self.assertEqual('baz', self.conf.get('foo', expand=True))
3961
self.assertEquals('baz', self.conf.get('foo', expand=True))
3680
3963
def test_expand_default_from_env(self):
3681
3964
self.conf.store._load_from_string('bar=baz')
3682
3965
self.registry.register(config.Option('foo', default_from_env=['FOO']))
3683
3966
self.overrideEnv('FOO', '{bar}')
3684
self.assertEqual('baz', self.conf.get('foo', expand=True))
3967
self.assertEquals('baz', self.conf.get('foo', expand=True))
3686
3969
def test_expand_default_on_failed_conversion(self):
3687
3970
self.conf.store._load_from_string('baz=bogus\nbar=42\nfoo={baz}')
3688
3971
self.registry.register(
3689
3972
config.Option('foo', default=u'{bar}',
3690
3973
from_unicode=config.int_from_store))
3691
self.assertEqual(42, self.conf.get('foo', expand=True))
3974
self.assertEquals(42, self.conf.get('foo', expand=True))
3693
3976
def test_env_adding_options(self):
3694
3977
self.assertExpansion('bar', '{foo}', {'foo': 'bar'})
3805
4088
[/another/branch/path]
3808
self.assertRaises(config.ExpandingUnknownOption,
4091
self.assertRaises(errors.ExpandingUnknownOption,
3809
4092
c.get, 'bar', expand=True)
3811
4094
def test_cross_related_sections(self):
3812
c = self.get_config('/project/branch/path', '''
4095
c = self.get_config('/project/branch/path','''
3816
4099
[/project/branch/path]
3819
self.assertEqual('quux', c.get('bar', expand=True))
4102
self.assertEquals('quux', c.get('bar', expand=True))
3822
4105
class TestStackCrossStoresExpand(tests.TestCaseWithTransport):
3938
4221
def test_simple_set(self):
3939
4222
conf = self.get_stack(self)
3940
self.assertEqual(None, conf.get('foo'))
4223
self.assertEquals(None, conf.get('foo'))
3941
4224
conf.set('foo', 'baz')
3942
4225
# Did we get it back ?
3943
self.assertEqual('baz', conf.get('foo'))
4226
self.assertEquals('baz', conf.get('foo'))
3945
4228
def test_set_creates_a_new_section(self):
3946
4229
conf = self.get_stack(self)
3947
4230
conf.set('foo', 'baz')
3948
self.assertEqual, 'baz', conf.get('foo')
4231
self.assertEquals, 'baz', conf.get('foo')
3950
4233
def test_set_hook(self):
3993
4276
create_configs(self)
3995
4278
def test_no_variable(self):
3996
# Using branch should query branch, locations and breezy
4279
# Using branch should query branch, locations and bazaar
3997
4280
self.assertOptions([], self.branch_config)
3999
def test_option_in_breezy(self):
4000
self.breezy_config.set_user_option('file', 'breezy')
4001
self.assertOptions([('file', 'breezy', 'DEFAULT', 'breezy')],
4282
def test_option_in_bazaar(self):
4283
self.bazaar_config.set_user_option('file', 'bazaar')
4284
self.assertOptions([('file', 'bazaar', 'DEFAULT', 'bazaar')],
4004
4287
def test_option_in_locations(self):
4005
4288
self.locations_config.set_user_option('file', 'locations')
4012
4295
self.assertOptions([('file', 'branch', 'DEFAULT', 'branch')],
4013
4296
self.branch_config)
4015
def test_option_in_breezy_and_branch(self):
4016
self.breezy_config.set_user_option('file', 'breezy')
4298
def test_option_in_bazaar_and_branch(self):
4299
self.bazaar_config.set_user_option('file', 'bazaar')
4017
4300
self.branch_config.set_user_option('file', 'branch')
4018
4301
self.assertOptions([('file', 'branch', 'DEFAULT', 'branch'),
4019
('file', 'breezy', 'DEFAULT', 'breezy'),],
4302
('file', 'bazaar', 'DEFAULT', 'bazaar'),],
4020
4303
self.branch_config)
4022
4305
def test_option_in_branch_and_locations(self):
4028
4311
('file', 'branch', 'DEFAULT', 'branch'),],
4029
4312
self.branch_config)
4031
def test_option_in_breezy_locations_and_branch(self):
4032
self.breezy_config.set_user_option('file', 'breezy')
4314
def test_option_in_bazaar_locations_and_branch(self):
4315
self.bazaar_config.set_user_option('file', 'bazaar')
4033
4316
self.locations_config.set_user_option('file', 'locations')
4034
4317
self.branch_config.set_user_option('file', 'branch')
4035
4318
self.assertOptions(
4036
4319
[('file', 'locations', self.tree.basedir, 'locations'),
4037
4320
('file', 'branch', 'DEFAULT', 'branch'),
4038
('file', 'breezy', 'DEFAULT', 'breezy'),],
4321
('file', 'bazaar', 'DEFAULT', 'bazaar'),],
4039
4322
self.branch_config)
4049
4332
self.locations_config.remove_user_option('file', self.tree.basedir)
4050
4333
self.assertOptions(
4051
4334
[('file', 'branch', 'DEFAULT', 'branch'),
4052
('file', 'breezy', 'DEFAULT', 'breezy'),],
4335
('file', 'bazaar', 'DEFAULT', 'bazaar'),],
4053
4336
self.branch_config)
4055
4338
def test_remove_in_branch(self):
4056
4339
self.branch_config.remove_user_option('file')
4057
4340
self.assertOptions(
4058
4341
[('file', 'locations', self.tree.basedir, 'locations'),
4059
('file', 'breezy', 'DEFAULT', 'breezy'),],
4342
('file', 'bazaar', 'DEFAULT', 'bazaar'),],
4060
4343
self.branch_config)
4062
def test_remove_in_breezy(self):
4063
self.breezy_config.remove_user_option('file')
4345
def test_remove_in_bazaar(self):
4346
self.bazaar_config.remove_user_option('file')
4064
4347
self.assertOptions(
4065
4348
[('file', 'locations', self.tree.basedir, 'locations'),
4066
4349
('file', 'branch', 'DEFAULT', 'branch'),],
4130
4413
self.assertSectionNames([self.tree.basedir, None, 'DEFAULT'],
4131
4414
self.branch_config)
4133
def test_breezy_named_section(self):
4416
def test_bazaar_named_section(self):
4134
4417
# We need to cheat as the API doesn't give direct access to sections
4135
4418
# other than DEFAULT.
4136
self.breezy_config.set_alias('breezy', 'bzr')
4137
self.assertSectionNames(['ALIASES'], self.breezy_config, 'ALIASES')
4419
self.bazaar_config.set_alias('bazaar', 'bzr')
4420
self.assertSectionNames(['ALIASES'], self.bazaar_config, 'ALIASES')
4140
4423
class TestSharedStores(tests.TestCaseInTempDir):
4142
def test_breezy_conf_shared(self):
4425
def test_bazaar_conf_shared(self):
4143
4426
g1 = config.GlobalStack()
4144
4427
g2 = config.GlobalStack()
4145
4428
# The two stacks share the same store
4146
4429
self.assertIs(g1.store, g2.store)
4149
class TestAuthenticationConfigFilePermissions(tests.TestCaseInTempDir):
4150
"""Test warning for permissions of authentication.conf."""
4153
super(TestAuthenticationConfigFilePermissions, self).setUp()
4154
self.path = osutils.pathjoin(self.test_dir, 'authentication.conf')
4155
with open(self.path, 'w') as f:
4156
f.write(b"""[broken]
4159
port=port # Error: Not an int
4161
self.overrideAttr(config, 'authentication_config_filename',
4163
osutils.chmod_if_possible(self.path, 0o755)
4165
def test_check_warning(self):
4166
conf = config.AuthenticationConfig()
4167
self.assertEqual(conf._filename, self.path)
4168
self.assertContainsRe(self.get_log(),
4169
'Saved passwords may be accessible by other users.')
4171
def test_check_suppressed_warning(self):
4172
global_config = config.GlobalConfig()
4173
global_config.set_user_option('suppress_warnings',
4174
'insecure_permissions')
4175
conf = config.AuthenticationConfig()
4176
self.assertEqual(conf._filename, self.path)
4177
self.assertNotContainsRe(self.get_log(),
4178
'Saved passwords may be accessible by other users.')
4181
4432
class TestAuthenticationConfigFile(tests.TestCase):
4182
4433
"""Test the authentication.conf file matching"""
4191
4442
user = credentials['user']
4192
4443
password = credentials['password']
4193
self.assertEqual(expected_user, user)
4194
self.assertEqual(expected_password, password)
4444
self.assertEquals(expected_user, user)
4445
self.assertEquals(expected_password, password)
4196
4447
def test_empty_config(self):
4197
conf = config.AuthenticationConfig(_file=BytesIO())
4198
self.assertEqual({}, conf._get_config())
4448
conf = config.AuthenticationConfig(_file=StringIO())
4449
self.assertEquals({}, conf._get_config())
4199
4450
self._got_user_passwd(None, None, conf, 'http', 'foo.net')
4201
4452
def test_non_utf8_config(self):
4202
conf = config.AuthenticationConfig(_file=BytesIO(b'foo = bar\xff'))
4203
self.assertRaises(config.ConfigContentError, conf._get_config)
4453
conf = config.AuthenticationConfig(_file=StringIO(
4455
self.assertRaises(errors.ConfigContentError, conf._get_config)
4205
4457
def test_missing_auth_section_header(self):
4206
conf = config.AuthenticationConfig(_file=BytesIO(b'foo = bar'))
4458
conf = config.AuthenticationConfig(_file=StringIO('foo = bar'))
4207
4459
self.assertRaises(ValueError, conf.get_credentials, 'ftp', 'foo.net')
4209
4461
def test_auth_section_header_not_closed(self):
4210
conf = config.AuthenticationConfig(_file=BytesIO(b'[DEF'))
4211
self.assertRaises(config.ParseConfigError, conf._get_config)
4462
conf = config.AuthenticationConfig(_file=StringIO('[DEF'))
4463
self.assertRaises(errors.ParseConfigError, conf._get_config)
4213
4465
def test_auth_value_not_boolean(self):
4214
conf = config.AuthenticationConfig(_file=BytesIO(b"""\
4466
conf = config.AuthenticationConfig(_file=StringIO(
4218
4470
verify_certificates=askme # Error: Not a boolean
4427
4683
'scheme': scheme, 'host': host, 'port': port,
4428
4684
'user': user, 'realm': realm}
4430
ui.ui_factory = tests.TestUIFactory(stdin=password + '\n')
4686
stdout = tests.StringIOWrapper()
4687
stderr = tests.StringIOWrapper()
4688
ui.ui_factory = tests.TestUIFactory(stdin=password + '\n',
4689
stdout=stdout, stderr=stderr)
4431
4690
# We use an empty conf so that the user is always prompted
4432
4691
conf = config.AuthenticationConfig()
4433
self.assertEqual(password,
4692
self.assertEquals(password,
4434
4693
conf.get_password(scheme, host, user, port=port,
4435
4694
realm=realm, path=path))
4436
self.assertEqual(expected_prompt, ui.ui_factory.stderr.getvalue())
4437
self.assertEqual('', ui.ui_factory.stdout.getvalue())
4695
self.assertEquals(expected_prompt, stderr.getvalue())
4696
self.assertEquals('', stdout.getvalue())
4439
4698
def _check_default_username_prompt(self, expected_prompt_format, scheme,
4440
4699
host=None, port=None, realm=None,
4445
4704
expected_prompt = expected_prompt_format % {
4446
4705
'scheme': scheme, 'host': host, 'port': port,
4447
4706
'realm': realm}
4448
ui.ui_factory = tests.TestUIFactory(stdin=username+ '\n')
4707
stdout = tests.StringIOWrapper()
4708
stderr = tests.StringIOWrapper()
4709
ui.ui_factory = tests.TestUIFactory(stdin=username+ '\n',
4710
stdout=stdout, stderr=stderr)
4449
4711
# We use an empty conf so that the user is always prompted
4450
4712
conf = config.AuthenticationConfig()
4451
self.assertEqual(username, conf.get_user(scheme, host, port=port,
4713
self.assertEquals(username, conf.get_user(scheme, host, port=port,
4452
4714
realm=realm, path=path, ask=True))
4453
self.assertEqual(expected_prompt, ui.ui_factory.stderr.getvalue())
4454
self.assertEqual('', ui.ui_factory.stdout.getvalue())
4715
self.assertEquals(expected_prompt, stderr.getvalue())
4716
self.assertEquals('', stdout.getvalue())
4456
4718
def test_username_defaults_prompts(self):
4457
4719
# HTTP prompts can't be tested here, see test_http.py
4496
4759
password=jimpass
4498
4761
entered_password = 'typed-by-hand'
4499
ui.ui_factory = tests.TestUIFactory(stdin=entered_password + '\n')
4762
stdout = tests.StringIOWrapper()
4763
stderr = tests.StringIOWrapper()
4764
ui.ui_factory = tests.TestUIFactory(stdin=entered_password + '\n',
4765
stdout=stdout, stderr=stderr)
4501
4767
# Since the password defined in the authentication config is ignored,
4502
4768
# the user is prompted
4503
self.assertEqual(entered_password,
4769
self.assertEquals(entered_password,
4504
4770
conf.get_password('ssh', 'bar.org', user='jim'))
4505
4771
self.assertContainsRe(
4506
4772
self.get_log(),
4507
'password ignored in section \\[ssh with password\\]')
4773
'password ignored in section \[ssh with password\]')
4509
4775
def test_ssh_without_password_doesnt_emit_warning(self):
4510
conf = config.AuthenticationConfig(_file=BytesIO(b"""
4776
conf = config.AuthenticationConfig(_file=StringIO(
4511
4778
[ssh with password]
4516
4783
entered_password = 'typed-by-hand'
4517
ui.ui_factory = tests.TestUIFactory(stdin=entered_password + '\n')
4784
stdout = tests.StringIOWrapper()
4785
stderr = tests.StringIOWrapper()
4786
ui.ui_factory = tests.TestUIFactory(stdin=entered_password + '\n',
4519
4790
# Since the password defined in the authentication config is ignored,
4520
4791
# the user is prompted
4521
self.assertEqual(entered_password,
4792
self.assertEquals(entered_password,
4522
4793
conf.get_password('ssh', 'bar.org', user='jim'))
4523
4794
# No warning shoud be emitted since there is no password. We are only
4524
4795
# providing "user".
4525
4796
self.assertNotContainsRe(
4526
4797
self.get_log(),
4527
'password ignored in section \\[ssh with password\\]')
4798
'password ignored in section \[ssh with password\]')
4529
4800
def test_uses_fallback_stores(self):
4530
4801
self.overrideAttr(config, 'credential_store_registry',
4532
4803
store = StubCredentialStore()
4533
4804
store.add_credentials("http", "example.com", "joe", "secret")
4534
4805
config.credential_store_registry.register("stub", store, fallback=True)
4535
conf = config.AuthenticationConfig(_file=BytesIO())
4806
conf = config.AuthenticationConfig(_file=StringIO())
4536
4807
creds = conf.get_credentials("http", "example.com")
4537
self.assertEqual("joe", creds["user"])
4538
self.assertEqual("secret", creds["password"])
4808
self.assertEquals("joe", creds["user"])
4809
self.assertEquals("secret", creds["password"])
4541
4812
class StubCredentialStore(config.CredentialStore):
4587
4858
def test_fallback_none_registered(self):
4588
4859
r = config.CredentialStoreRegistry()
4589
self.assertEqual(None,
4860
self.assertEquals(None,
4590
4861
r.get_fallback_credentials("http", "example.com"))
4592
4863
def test_register(self):
4593
4864
r = config.CredentialStoreRegistry()
4594
4865
r.register("stub", StubCredentialStore(), fallback=False)
4595
4866
r.register("another", StubCredentialStore(), fallback=True)
4596
self.assertEqual(["another", "stub"], r.keys())
4867
self.assertEquals(["another", "stub"], r.keys())
4598
4869
def test_register_lazy(self):
4599
4870
r = config.CredentialStoreRegistry()
4600
r.register_lazy("stub", "breezy.tests.test_config",
4871
r.register_lazy("stub", "bzrlib.tests.test_config",
4601
4872
"StubCredentialStore", fallback=False)
4602
self.assertEqual(["stub"], r.keys())
4873
self.assertEquals(["stub"], r.keys())
4603
4874
self.assertIsInstance(r.get_credential_store("stub"),
4604
4875
StubCredentialStore)
4607
4878
r = config.CredentialStoreRegistry()
4608
4879
r.register("stub1", None, fallback=False)
4609
4880
r.register("stub2", None, fallback=True)
4610
self.assertEqual(False, r.is_fallback("stub1"))
4611
self.assertEqual(True, r.is_fallback("stub2"))
4881
self.assertEquals(False, r.is_fallback("stub1"))
4882
self.assertEquals(True, r.is_fallback("stub2"))
4613
4884
def test_no_fallback(self):
4614
4885
r = config.CredentialStoreRegistry()
4615
4886
store = CountingCredentialStore()
4616
4887
r.register("count", store, fallback=False)
4617
self.assertEqual(None,
4888
self.assertEquals(None,
4618
4889
r.get_fallback_credentials("http", "example.com"))
4619
self.assertEqual(0, store._calls)
4890
self.assertEquals(0, store._calls)
4621
4892
def test_fallback_credentials(self):
4622
4893
r = config.CredentialStoreRegistry()
4725
4996
r = config._get_default_mail_domain('multiple_lines')
4726
self.assertEqual('domainname.com', r)
4997
self.assertEquals('domainname.com', r)
4729
5000
class EmailOptionTests(tests.TestCase):
4731
def test_default_email_uses_BRZ_EMAIL(self):
5002
def test_default_email_uses_BZR_EMAIL(self):
4732
5003
conf = config.MemoryStack('email=jelmer@debian.org')
4733
# BRZ_EMAIL takes precedence over EMAIL
4734
self.overrideEnv('BRZ_EMAIL', 'jelmer@samba.org')
5004
# BZR_EMAIL takes precedence over EMAIL
5005
self.overrideEnv('BZR_EMAIL', 'jelmer@samba.org')
4735
5006
self.overrideEnv('EMAIL', 'jelmer@apache.org')
4736
self.assertEqual('jelmer@samba.org', conf.get('email'))
5007
self.assertEquals('jelmer@samba.org', conf.get('email'))
4738
5009
def test_default_email_uses_EMAIL(self):
4739
5010
conf = config.MemoryStack('')
4740
self.overrideEnv('BRZ_EMAIL', None)
5011
self.overrideEnv('BZR_EMAIL', None)
4741
5012
self.overrideEnv('EMAIL', 'jelmer@apache.org')
4742
self.assertEqual('jelmer@apache.org', conf.get('email'))
5013
self.assertEquals('jelmer@apache.org', conf.get('email'))
4744
def test_BRZ_EMAIL_overrides(self):
5015
def test_BZR_EMAIL_overrides(self):
4745
5016
conf = config.MemoryStack('email=jelmer@debian.org')
4746
self.overrideEnv('BRZ_EMAIL', 'jelmer@apache.org')
4747
self.assertEqual('jelmer@apache.org', conf.get('email'))
4748
self.overrideEnv('BRZ_EMAIL', None)
5017
self.overrideEnv('BZR_EMAIL', 'jelmer@apache.org')
5018
self.assertEquals('jelmer@apache.org', conf.get('email'))
5019
self.overrideEnv('BZR_EMAIL', None)
4749
5020
self.overrideEnv('EMAIL', 'jelmer@samba.org')
4750
self.assertEqual('jelmer@debian.org', conf.get('email'))
5021
self.assertEquals('jelmer@debian.org', conf.get('email'))
4753
5024
class MailClientOptionTests(tests.TestCase):