~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_config.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-07-13 19:02:12 UTC
  • mfrom: (4986.2.8 deprecation)
  • Revision ID: pqm@pqm.ubuntu.com-20100713190212-bnayd5moplwtxhhb
(mbp) change some test tearDowns to addCleanup or overrideAttr (Martin Pool)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2008 Canonical Ltd
2
 
#   Authors: Robert Collins <robert.collins@canonical.com>
 
1
# Copyright (C) 2005-2010 Canonical Ltd
3
2
#
4
3
# This program is free software; you can redistribute it and/or modify
5
4
# it under the terms of the GNU General Public License as published by
26
25
    branch,
27
26
    bzrdir,
28
27
    config,
 
28
    diff,
29
29
    errors,
30
30
    osutils,
31
31
    mail_client,
43
43
[DEFAULT]
44
44
email=Erik B\u00e5gfors <erik@bagfors.nu>
45
45
editor=vim
 
46
change_editor=vimdiff -of @new_path @old_path
46
47
gpg_signing_command=gnome-gpg
47
48
log_format=short
48
49
user_global_option=something
150
151
        self._transport = self.control_files = \
151
152
            FakeControlFilesAndTransport(user_id=user_id)
152
153
 
 
154
    def _get_config(self):
 
155
        return config.TransportConfig(self._transport, 'branch.conf')
 
156
 
153
157
    def lock_write(self):
154
158
        pass
155
159
 
206
210
        self._calls.append('_get_signature_checking')
207
211
        return self._signatures
208
212
 
 
213
    def _get_change_editor(self):
 
214
        self._calls.append('_get_change_editor')
 
215
        return 'vimdiff -fo @new_path @old_path'
 
216
 
209
217
 
210
218
bool_config = """[DEFAULT]
211
219
active = true
312
320
        my_config = config.Config()
313
321
        self.assertEqual('long', my_config.log_format())
314
322
 
 
323
    def test_get_change_editor(self):
 
324
        my_config = InstrumentedConfig()
 
325
        change_editor = my_config.get_change_editor('old_tree', 'new_tree')
 
326
        self.assertEqual(['_get_change_editor'], my_config._calls)
 
327
        self.assertIs(diff.DiffFromTool, change_editor.__class__)
 
328
        self.assertEqual(['vimdiff', '-fo', '@new_path', '@old_path'],
 
329
                         change_editor.command_template)
 
330
 
315
331
 
316
332
class TestConfigPath(tests.TestCase):
317
333
 
318
334
    def setUp(self):
319
335
        super(TestConfigPath, self).setUp()
320
336
        os.environ['HOME'] = '/home/bogus'
 
337
        os.environ['XDG_CACHE_DIR'] = ''
321
338
        if sys.platform == 'win32':
322
339
            os.environ['BZR_HOME'] = \
323
340
                r'C:\Documents and Settings\bogus\Application Data'
345
362
        self.assertEqual(config.authentication_config_filename(),
346
363
                         self.bzr_home + '/authentication.conf')
347
364
 
 
365
    def test_xdg_cache_dir(self):
 
366
        self.assertEqual(config.xdg_cache_dir(),
 
367
            '/home/bogus/.cache')
 
368
 
348
369
 
349
370
class TestIniConfig(tests.TestCase):
350
371
 
 
372
    def make_config_parser(self, s):
 
373
        conf = config.IniBasedConfig(None)
 
374
        parser = conf._get_parser(file=StringIO(s.encode('utf-8')))
 
375
        return conf, parser
 
376
 
 
377
 
 
378
class TestIniConfigBuilding(TestIniConfig):
 
379
 
351
380
    def test_contructs(self):
352
381
        my_config = config.IniBasedConfig("nothing")
353
382
 
365
394
        self.failUnless(my_config._get_parser() is parser)
366
395
 
367
396
 
 
397
class TestGetUserOptionAs(TestIniConfig):
 
398
 
 
399
    def test_get_user_option_as_bool(self):
 
400
        conf, parser = self.make_config_parser("""
 
401
a_true_bool = true
 
402
a_false_bool = 0
 
403
an_invalid_bool = maybe
 
404
a_list = hmm, who knows ? # This is interpreted as a list !
 
405
""")
 
406
        get_bool = conf.get_user_option_as_bool
 
407
        self.assertEqual(True, get_bool('a_true_bool'))
 
408
        self.assertEqual(False, get_bool('a_false_bool'))
 
409
        warnings = []
 
410
        def warning(*args):
 
411
            warnings.append(args[0] % args[1:])
 
412
        self.overrideAttr(trace, 'warning', warning)
 
413
        msg = 'Value "%s" is not a boolean for "%s"'
 
414
        self.assertIs(None, get_bool('an_invalid_bool'))
 
415
        self.assertEquals(msg % ('maybe', 'an_invalid_bool'), warnings[0])
 
416
        warnings = []
 
417
        self.assertIs(None, get_bool('not_defined_in_this_config'))
 
418
        self.assertEquals([], warnings)
 
419
 
 
420
    def test_get_user_option_as_list(self):
 
421
        conf, parser = self.make_config_parser("""
 
422
a_list = a,b,c
 
423
length_1 = 1,
 
424
one_item = x
 
425
""")
 
426
        get_list = conf.get_user_option_as_list
 
427
        self.assertEqual(['a', 'b', 'c'], get_list('a_list'))
 
428
        self.assertEqual(['1'], get_list('length_1'))
 
429
        self.assertEqual('x', conf.get_user_option('one_item'))
 
430
        # automatically cast to list
 
431
        self.assertEqual(['x'], get_list('one_item'))
 
432
 
 
433
 
 
434
class TestSupressWarning(TestIniConfig):
 
435
 
 
436
    def make_warnings_config(self, s):
 
437
        conf, parser = self.make_config_parser(s)
 
438
        return conf.suppress_warning
 
439
 
 
440
    def test_suppress_warning_unknown(self):
 
441
        suppress_warning = self.make_warnings_config('')
 
442
        self.assertEqual(False, suppress_warning('unknown_warning'))
 
443
 
 
444
    def test_suppress_warning_known(self):
 
445
        suppress_warning = self.make_warnings_config('suppress_warnings=a,b')
 
446
        self.assertEqual(False, suppress_warning('c'))
 
447
        self.assertEqual(True, suppress_warning('a'))
 
448
        self.assertEqual(True, suppress_warning('b'))
 
449
 
 
450
 
368
451
class TestGetConfig(tests.TestCase):
369
452
 
370
453
    def test_constructs(self):
604
687
        my_config = self._get_sample_config()
605
688
        self.assertEqual(sample_long_alias, my_config.get_alias('ll'))
606
689
 
 
690
    def test_get_change_editor(self):
 
691
        my_config = self._get_sample_config()
 
692
        change_editor = my_config.get_change_editor('old', 'new')
 
693
        self.assertIs(diff.DiffFromTool, change_editor.__class__)
 
694
        self.assertEqual('vimdiff -of @new_path @old_path',
 
695
                         ' '.join(change_editor.command_template))
 
696
 
 
697
    def test_get_no_change_editor(self):
 
698
        my_config = self._get_empty_config()
 
699
        change_editor = my_config.get_change_editor('old', 'new')
 
700
        self.assertIs(None, change_editor)
 
701
 
607
702
 
608
703
class TestGlobalConfigSavingOptions(tests.TestCaseInTempDir):
609
704
 
1207
1302
 
1208
1303
    def test_set_unset_default_stack_on(self):
1209
1304
        my_dir = self.make_bzrdir('.')
1210
 
        bzrdir_config = config.BzrDirConfig(my_dir.transport)
 
1305
        bzrdir_config = config.BzrDirConfig(my_dir)
1211
1306
        self.assertIs(None, bzrdir_config.get_default_stack_on())
1212
1307
        bzrdir_config.set_default_stack_on('Foo')
1213
1308
        self.assertEqual('Foo', bzrdir_config._config.get_option(
1456
1551
class TestAuthenticationConfig(tests.TestCase):
1457
1552
    """Test AuthenticationConfig behaviour"""
1458
1553
 
1459
 
    def _check_default_prompt(self, expected_prompt_format, scheme,
1460
 
                              host=None, port=None, realm=None, path=None):
 
1554
    def _check_default_password_prompt(self, expected_prompt_format, scheme,
 
1555
                                       host=None, port=None, realm=None,
 
1556
                                       path=None):
1461
1557
        if host is None:
1462
1558
            host = 'bar.org'
1463
1559
        user, password = 'jim', 'precious'
1466
1562
            'user': user, 'realm': realm}
1467
1563
 
1468
1564
        stdout = tests.StringIOWrapper()
 
1565
        stderr = tests.StringIOWrapper()
1469
1566
        ui.ui_factory = tests.TestUIFactory(stdin=password + '\n',
1470
 
                                            stdout=stdout)
 
1567
                                            stdout=stdout, stderr=stderr)
1471
1568
        # We use an empty conf so that the user is always prompted
1472
1569
        conf = config.AuthenticationConfig()
1473
1570
        self.assertEquals(password,
1474
1571
                          conf.get_password(scheme, host, user, port=port,
1475
1572
                                            realm=realm, path=path))
1476
 
        self.assertEquals(stdout.getvalue(), expected_prompt)
1477
 
 
1478
 
    def test_default_prompts(self):
1479
 
        # HTTP prompts can't be tested here, see test_http.py
1480
 
        self._check_default_prompt('FTP %(user)s@%(host)s password: ', 'ftp')
1481
 
        self._check_default_prompt('FTP %(user)s@%(host)s:%(port)d password: ',
1482
 
                                   'ftp', port=10020)
1483
 
 
1484
 
        self._check_default_prompt('SSH %(user)s@%(host)s:%(port)d password: ',
1485
 
                                   'ssh', port=12345)
 
1573
        self.assertEquals(expected_prompt, stderr.getvalue())
 
1574
        self.assertEquals('', stdout.getvalue())
 
1575
 
 
1576
    def _check_default_username_prompt(self, expected_prompt_format, scheme,
 
1577
                                       host=None, port=None, realm=None,
 
1578
                                       path=None):
 
1579
        if host is None:
 
1580
            host = 'bar.org'
 
1581
        username = 'jim'
 
1582
        expected_prompt = expected_prompt_format % {
 
1583
            'scheme': scheme, 'host': host, 'port': port,
 
1584
            'realm': realm}
 
1585
        stdout = tests.StringIOWrapper()
 
1586
        stderr = tests.StringIOWrapper()
 
1587
        ui.ui_factory = tests.TestUIFactory(stdin=username+ '\n',
 
1588
                                            stdout=stdout, stderr=stderr)
 
1589
        # We use an empty conf so that the user is always prompted
 
1590
        conf = config.AuthenticationConfig()
 
1591
        self.assertEquals(username, conf.get_user(scheme, host, port=port,
 
1592
                          realm=realm, path=path, ask=True))
 
1593
        self.assertEquals(expected_prompt, stderr.getvalue())
 
1594
        self.assertEquals('', stdout.getvalue())
 
1595
 
 
1596
    def test_username_defaults_prompts(self):
 
1597
        # HTTP prompts can't be tested here, see test_http.py
 
1598
        self._check_default_username_prompt('FTP %(host)s username: ', 'ftp')
 
1599
        self._check_default_username_prompt(
 
1600
            'FTP %(host)s:%(port)d username: ', 'ftp', port=10020)
 
1601
        self._check_default_username_prompt(
 
1602
            'SSH %(host)s:%(port)d username: ', 'ssh', port=12345)
 
1603
 
 
1604
    def test_username_default_no_prompt(self):
 
1605
        conf = config.AuthenticationConfig()
 
1606
        self.assertEquals(None,
 
1607
            conf.get_user('ftp', 'example.com'))
 
1608
        self.assertEquals("explicitdefault",
 
1609
            conf.get_user('ftp', 'example.com', default="explicitdefault"))
 
1610
 
 
1611
    def test_password_default_prompts(self):
 
1612
        # HTTP prompts can't be tested here, see test_http.py
 
1613
        self._check_default_password_prompt(
 
1614
            'FTP %(user)s@%(host)s password: ', 'ftp')
 
1615
        self._check_default_password_prompt(
 
1616
            'FTP %(user)s@%(host)s:%(port)d password: ', 'ftp', port=10020)
 
1617
        self._check_default_password_prompt(
 
1618
            'SSH %(user)s@%(host)s:%(port)d password: ', 'ssh', port=12345)
1486
1619
        # SMTP port handling is a bit special (it's handled if embedded in the
1487
1620
        # host too)
1488
1621
        # FIXME: should we: forbid that, extend it to other schemes, leave
1489
1622
        # things as they are that's fine thank you ?
1490
 
        self._check_default_prompt('SMTP %(user)s@%(host)s password: ',
1491
 
                                   'smtp')
1492
 
        self._check_default_prompt('SMTP %(user)s@%(host)s password: ',
1493
 
                                   'smtp', host='bar.org:10025')
1494
 
        self._check_default_prompt(
 
1623
        self._check_default_password_prompt('SMTP %(user)s@%(host)s password: ',
 
1624
                                            'smtp')
 
1625
        self._check_default_password_prompt('SMTP %(user)s@%(host)s password: ',
 
1626
                                            'smtp', host='bar.org:10025')
 
1627
        self._check_default_password_prompt(
1495
1628
            'SMTP %(user)s@%(host)s:%(port)d password: ',
1496
1629
            'smtp', port=10025)
1497
1630
 
1506
1639
"""))
1507
1640
        entered_password = 'typed-by-hand'
1508
1641
        stdout = tests.StringIOWrapper()
 
1642
        stderr = tests.StringIOWrapper()
1509
1643
        ui.ui_factory = tests.TestUIFactory(stdin=entered_password + '\n',
1510
 
                                            stdout=stdout)
 
1644
                                            stdout=stdout, stderr=stderr)
1511
1645
 
1512
1646
        # Since the password defined in the authentication config is ignored,
1513
1647
        # the user is prompted
1514
1648
        self.assertEquals(entered_password,
1515
1649
                          conf.get_password('ssh', 'bar.org', user='jim'))
1516
1650
        self.assertContainsRe(
1517
 
            self._get_log(keep_log_file=True),
 
1651
            self.get_log(),
1518
1652
            'password ignored in section \[ssh with password\]')
1519
1653
 
1520
1654
    def test_ssh_without_password_doesnt_emit_warning(self):
1527
1661
"""))
1528
1662
        entered_password = 'typed-by-hand'
1529
1663
        stdout = tests.StringIOWrapper()
 
1664
        stderr = tests.StringIOWrapper()
1530
1665
        ui.ui_factory = tests.TestUIFactory(stdin=entered_password + '\n',
1531
 
                                            stdout=stdout)
 
1666
                                            stdout=stdout,
 
1667
                                            stderr=stderr)
1532
1668
 
1533
1669
        # Since the password defined in the authentication config is ignored,
1534
1670
        # the user is prompted
1537
1673
        # No warning shoud be emitted since there is no password. We are only
1538
1674
        # providing "user".
1539
1675
        self.assertNotContainsRe(
1540
 
            self._get_log(keep_log_file=True),
 
1676
            self.get_log(),
1541
1677
            'password ignored in section \[ssh with password\]')
1542
1678
 
 
1679
    def test_uses_fallback_stores(self):
 
1680
        self.overrideAttr(config, 'credential_store_registry',
 
1681
                          config.CredentialStoreRegistry())
 
1682
        store = StubCredentialStore()
 
1683
        store.add_credentials("http", "example.com", "joe", "secret")
 
1684
        config.credential_store_registry.register("stub", store, fallback=True)
 
1685
        conf = config.AuthenticationConfig(_file=StringIO())
 
1686
        creds = conf.get_credentials("http", "example.com")
 
1687
        self.assertEquals("joe", creds["user"])
 
1688
        self.assertEquals("secret", creds["password"])
 
1689
 
 
1690
 
 
1691
class StubCredentialStore(config.CredentialStore):
 
1692
 
 
1693
    def __init__(self):
 
1694
        self._username = {}
 
1695
        self._password = {}
 
1696
 
 
1697
    def add_credentials(self, scheme, host, user, password=None):
 
1698
        self._username[(scheme, host)] = user
 
1699
        self._password[(scheme, host)] = password
 
1700
 
 
1701
    def get_credentials(self, scheme, host, port=None, user=None,
 
1702
        path=None, realm=None):
 
1703
        key = (scheme, host)
 
1704
        if not key in self._username:
 
1705
            return None
 
1706
        return { "scheme": scheme, "host": host, "port": port,
 
1707
                "user": self._username[key], "password": self._password[key]}
 
1708
 
 
1709
 
 
1710
class CountingCredentialStore(config.CredentialStore):
 
1711
 
 
1712
    def __init__(self):
 
1713
        self._calls = 0
 
1714
 
 
1715
    def get_credentials(self, scheme, host, port=None, user=None,
 
1716
        path=None, realm=None):
 
1717
        self._calls += 1
 
1718
        return None
 
1719
 
1543
1720
 
1544
1721
class TestCredentialStoreRegistry(tests.TestCase):
1545
1722
 
1557
1734
        # 'unknown' so we use that as an never registered key.
1558
1735
        self.assertRaises(KeyError, r.get_credential_store, 'unknown')
1559
1736
 
 
1737
    def test_fallback_none_registered(self):
 
1738
        r = config.CredentialStoreRegistry()
 
1739
        self.assertEquals(None,
 
1740
                          r.get_fallback_credentials("http", "example.com"))
 
1741
 
 
1742
    def test_register(self):
 
1743
        r = config.CredentialStoreRegistry()
 
1744
        r.register("stub", StubCredentialStore(), fallback=False)
 
1745
        r.register("another", StubCredentialStore(), fallback=True)
 
1746
        self.assertEquals(["another", "stub"], r.keys())
 
1747
 
 
1748
    def test_register_lazy(self):
 
1749
        r = config.CredentialStoreRegistry()
 
1750
        r.register_lazy("stub", "bzrlib.tests.test_config",
 
1751
                        "StubCredentialStore", fallback=False)
 
1752
        self.assertEquals(["stub"], r.keys())
 
1753
        self.assertIsInstance(r.get_credential_store("stub"),
 
1754
                              StubCredentialStore)
 
1755
 
 
1756
    def test_is_fallback(self):
 
1757
        r = config.CredentialStoreRegistry()
 
1758
        r.register("stub1", None, fallback=False)
 
1759
        r.register("stub2", None, fallback=True)
 
1760
        self.assertEquals(False, r.is_fallback("stub1"))
 
1761
        self.assertEquals(True, r.is_fallback("stub2"))
 
1762
 
 
1763
    def test_no_fallback(self):
 
1764
        r = config.CredentialStoreRegistry()
 
1765
        store = CountingCredentialStore()
 
1766
        r.register("count", store, fallback=False)
 
1767
        self.assertEquals(None,
 
1768
                          r.get_fallback_credentials("http", "example.com"))
 
1769
        self.assertEquals(0, store._calls)
 
1770
 
 
1771
    def test_fallback_credentials(self):
 
1772
        r = config.CredentialStoreRegistry()
 
1773
        store = StubCredentialStore()
 
1774
        store.add_credentials("http", "example.com",
 
1775
                              "somebody", "geheim")
 
1776
        r.register("stub", store, fallback=True)
 
1777
        creds = r.get_fallback_credentials("http", "example.com")
 
1778
        self.assertEquals("somebody", creds["user"])
 
1779
        self.assertEquals("geheim", creds["password"])
 
1780
 
 
1781
    def test_fallback_first_wins(self):
 
1782
        r = config.CredentialStoreRegistry()
 
1783
        stub1 = StubCredentialStore()
 
1784
        stub1.add_credentials("http", "example.com",
 
1785
                              "somebody", "stub1")
 
1786
        r.register("stub1", stub1, fallback=True)
 
1787
        stub2 = StubCredentialStore()
 
1788
        stub2.add_credentials("http", "example.com",
 
1789
                              "somebody", "stub2")
 
1790
        r.register("stub2", stub1, fallback=True)
 
1791
        creds = r.get_fallback_credentials("http", "example.com")
 
1792
        self.assertEquals("somebody", creds["user"])
 
1793
        self.assertEquals("stub1", creds["password"])
 
1794
 
1560
1795
 
1561
1796
class TestPlainTextCredentialStore(tests.TestCase):
1562
1797