~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: 2008-09-09 15:09:12 UTC
  • mto: This revision was merged to the branch mainline in revision 3699.
  • Revision ID: john@arbash-meinel.com-20080909150912-wyttm8he1zsls2ck
Use the right timing function on win32

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2008, 2009 Canonical Ltd
 
1
# Copyright (C) 2005, 2006 Canonical Ltd
 
2
#   Authors: Robert Collins <robert.collins@canonical.com>
2
3
#
3
4
# This program is free software; you can redistribute it and/or modify
4
5
# it under the terms of the GNU General Public License as published by
12
13
#
13
14
# You should have received a copy of the GNU General Public License
14
15
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
 
17
18
"""Tests for finding and reading the bzr config file[s]."""
18
19
# import system imports here
149
150
        self._transport = self.control_files = \
150
151
            FakeControlFilesAndTransport(user_id=user_id)
151
152
 
152
 
    def _get_config(self):
153
 
        return config.TransportConfig(self._transport, 'branch.conf')
154
 
 
155
153
    def lock_write(self):
156
154
        pass
157
155
 
320
318
    def setUp(self):
321
319
        super(TestConfigPath, self).setUp()
322
320
        os.environ['HOME'] = '/home/bogus'
323
 
        os.environ['XDG_CACHE_DIR'] = ''
324
321
        if sys.platform == 'win32':
325
322
            os.environ['BZR_HOME'] = \
326
323
                r'C:\Documents and Settings\bogus\Application Data'
348
345
        self.assertEqual(config.authentication_config_filename(),
349
346
                         self.bzr_home + '/authentication.conf')
350
347
 
351
 
    def test_xdg_cache_dir(self):
352
 
        self.assertEqual(config.xdg_cache_dir(),
353
 
            '/home/bogus/.cache')
354
 
 
355
348
 
356
349
class TestIniConfig(tests.TestCase):
357
350
 
371
364
        parser = my_config._get_parser(file=config_file)
372
365
        self.failUnless(my_config._get_parser() is parser)
373
366
 
374
 
    def test_get_user_option_as_bool(self):
375
 
        config_file = StringIO("""
376
 
a_true_bool = true
377
 
a_false_bool = 0
378
 
an_invalid_bool = maybe
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'))
388
367
 
389
368
class TestGetConfig(tests.TestCase):
390
369
 
446
425
        locations = config.locations_config_filename()
447
426
        config.ensure_config_dir_exists()
448
427
        local_url = urlutils.local_path_to_url('branch')
449
 
        open(locations, 'wb').write('[%s]\nnickname = foobar'
 
428
        open(locations, 'wb').write('[%s]\nnickname = foobar' 
450
429
                                    % (local_url,))
451
430
        self.assertEqual('foobar', branch.nick)
452
431
 
457
436
 
458
437
        locations = config.locations_config_filename()
459
438
        config.ensure_config_dir_exists()
460
 
        open(locations, 'wb').write('[%s/branch]\nnickname = barry'
 
439
        open(locations, 'wb').write('[%s/branch]\nnickname = barry' 
461
440
                                    % (osutils.getcwd().encode('utf8'),))
462
441
        self.assertEqual('barry', branch.nick)
463
442
 
1228
1207
 
1229
1208
    def test_set_unset_default_stack_on(self):
1230
1209
        my_dir = self.make_bzrdir('.')
1231
 
        bzrdir_config = config.BzrDirConfig(my_dir)
 
1210
        bzrdir_config = config.BzrDirConfig(my_dir.transport)
1232
1211
        self.assertIs(None, bzrdir_config.get_default_stack_on())
1233
1212
        bzrdir_config.set_default_stack_on('Foo')
1234
1213
        self.assertEqual('Foo', bzrdir_config._config.get_option(
1284
1263
"""))
1285
1264
        self.assertRaises(ValueError, conf.get_credentials, 'ftp', 'foo.net')
1286
1265
 
1287
 
    def test_unknown_password_encoding(self):
1288
 
        conf = config.AuthenticationConfig(_file=StringIO(
1289
 
                """[broken]
1290
 
scheme=ftp
1291
 
user=joe
1292
 
password_encoding=unknown
1293
 
"""))
1294
 
        self.assertRaises(ValueError, conf.get_password,
1295
 
                          'ftp', 'foo.net', 'joe')
1296
 
 
1297
1266
    def test_credentials_for_scheme_host(self):
1298
1267
        conf = config.AuthenticationConfig(_file=StringIO(
1299
1268
                """# Identity on foo.net
1443
1412
        self.assertEquals(True, credentials.get('verify_certificates'))
1444
1413
 
1445
1414
 
1446
 
class TestAuthenticationStorage(tests.TestCaseInTempDir):
1447
 
 
1448
 
    def test_set_credentials(self):
1449
 
        conf = config.AuthenticationConfig()
1450
 
        conf.set_credentials('name', 'host', 'user', 'scheme', 'password',
1451
 
        99, path='/foo', verify_certificates=False, realm='realm')
1452
 
        credentials = conf.get_credentials(host='host', scheme='scheme',
1453
 
                                           port=99, path='/foo',
1454
 
                                           realm='realm')
1455
 
        CREDENTIALS = {'name': 'name', 'user': 'user', 'password': 'password',
1456
 
                       'verify_certificates': False, 'scheme': 'scheme', 
1457
 
                       'host': 'host', 'port': 99, 'path': '/foo', 
1458
 
                       'realm': 'realm'}
1459
 
        self.assertEqual(CREDENTIALS, credentials)
1460
 
        credentials_from_disk = config.AuthenticationConfig().get_credentials(
1461
 
            host='host', scheme='scheme', port=99, path='/foo', realm='realm')
1462
 
        self.assertEqual(CREDENTIALS, credentials_from_disk)
1463
 
 
1464
 
    def test_reset_credentials_different_name(self):
1465
 
        conf = config.AuthenticationConfig()
1466
 
        conf.set_credentials('name', 'host', 'user', 'scheme', 'password'),
1467
 
        conf.set_credentials('name2', 'host', 'user2', 'scheme', 'password'),
1468
 
        self.assertIs(None, conf._get_config().get('name'))
1469
 
        credentials = conf.get_credentials(host='host', scheme='scheme')
1470
 
        CREDENTIALS = {'name': 'name2', 'user': 'user2', 'password':
1471
 
                       'password', 'verify_certificates': True, 
1472
 
                       'scheme': 'scheme', 'host': 'host', 'port': None, 
1473
 
                       'path': None, 'realm': None}
1474
 
        self.assertEqual(CREDENTIALS, credentials)
1475
 
 
1476
 
 
1477
1415
class TestAuthenticationConfig(tests.TestCase):
1478
1416
    """Test AuthenticationConfig behaviour"""
1479
1417
 
1480
 
    def _check_default_password_prompt(self, expected_prompt_format, scheme,
1481
 
                                       host=None, port=None, realm=None,
1482
 
                                       path=None):
 
1418
    def _check_default_prompt(self, expected_prompt_format, scheme,
 
1419
                              host=None, port=None, realm=None, path=None):
1483
1420
        if host is None:
1484
1421
            host = 'bar.org'
1485
1422
        user, password = 'jim', 'precious'
1488
1425
            'user': user, 'realm': realm}
1489
1426
 
1490
1427
        stdout = tests.StringIOWrapper()
1491
 
        stderr = tests.StringIOWrapper()
1492
1428
        ui.ui_factory = tests.TestUIFactory(stdin=password + '\n',
1493
 
                                            stdout=stdout, stderr=stderr)
 
1429
                                            stdout=stdout)
1494
1430
        # We use an empty conf so that the user is always prompted
1495
1431
        conf = config.AuthenticationConfig()
1496
1432
        self.assertEquals(password,
1497
1433
                          conf.get_password(scheme, host, user, port=port,
1498
1434
                                            realm=realm, path=path))
1499
 
        self.assertEquals(expected_prompt, stderr.getvalue())
1500
 
        self.assertEquals('', stdout.getvalue())
1501
 
 
1502
 
    def _check_default_username_prompt(self, expected_prompt_format, scheme,
1503
 
                                       host=None, port=None, realm=None,
1504
 
                                       path=None):
1505
 
        if host is None:
1506
 
            host = 'bar.org'
1507
 
        username = 'jim'
1508
 
        expected_prompt = expected_prompt_format % {
1509
 
            'scheme': scheme, 'host': host, 'port': port,
1510
 
            'realm': realm}
1511
 
        stdout = tests.StringIOWrapper()
1512
 
        stderr = tests.StringIOWrapper()
1513
 
        ui.ui_factory = tests.TestUIFactory(stdin=username+ '\n',
1514
 
                                            stdout=stdout, stderr=stderr)
1515
 
        # We use an empty conf so that the user is always prompted
1516
 
        conf = config.AuthenticationConfig()
1517
 
        self.assertEquals(username, conf.get_user(scheme, host, port=port,
1518
 
                          realm=realm, path=path, ask=True))
1519
 
        self.assertEquals(expected_prompt, stderr.getvalue())
1520
 
        self.assertEquals('', stdout.getvalue())
1521
 
 
1522
 
    def test_username_defaults_prompts(self):
1523
 
        # HTTP prompts can't be tested here, see test_http.py
1524
 
        self._check_default_username_prompt('FTP %(host)s username: ', 'ftp')
1525
 
        self._check_default_username_prompt(
1526
 
            'FTP %(host)s:%(port)d username: ', 'ftp', port=10020)
1527
 
        self._check_default_username_prompt(
1528
 
            'SSH %(host)s:%(port)d username: ', 'ssh', port=12345)
1529
 
 
1530
 
    def test_username_default_no_prompt(self):
1531
 
        conf = config.AuthenticationConfig()
1532
 
        self.assertEquals(None,
1533
 
            conf.get_user('ftp', 'example.com'))
1534
 
        self.assertEquals("explicitdefault",
1535
 
            conf.get_user('ftp', 'example.com', default="explicitdefault"))
1536
 
 
1537
 
    def test_password_default_prompts(self):
1538
 
        # HTTP prompts can't be tested here, see test_http.py
1539
 
        self._check_default_password_prompt(
1540
 
            'FTP %(user)s@%(host)s password: ', 'ftp')
1541
 
        self._check_default_password_prompt(
1542
 
            'FTP %(user)s@%(host)s:%(port)d password: ', 'ftp', port=10020)
1543
 
        self._check_default_password_prompt(
1544
 
            'SSH %(user)s@%(host)s:%(port)d password: ', 'ssh', port=12345)
 
1435
        self.assertEquals(stdout.getvalue(), expected_prompt)
 
1436
 
 
1437
    def test_default_prompts(self):
 
1438
        # HTTP prompts can't be tested here, see test_http.py
 
1439
        self._check_default_prompt('FTP %(user)s@%(host)s password: ', 'ftp')
 
1440
        self._check_default_prompt('FTP %(user)s@%(host)s:%(port)d password: ',
 
1441
                                   'ftp', port=10020)
 
1442
 
 
1443
        self._check_default_prompt('SSH %(user)s@%(host)s:%(port)d password: ',
 
1444
                                   'ssh', port=12345)
1545
1445
        # SMTP port handling is a bit special (it's handled if embedded in the
1546
1446
        # host too)
1547
1447
        # FIXME: should we: forbid that, extend it to other schemes, leave
1548
1448
        # things as they are that's fine thank you ?
1549
 
        self._check_default_password_prompt('SMTP %(user)s@%(host)s password: ',
1550
 
                                            'smtp')
1551
 
        self._check_default_password_prompt('SMTP %(user)s@%(host)s password: ',
1552
 
                                            'smtp', host='bar.org:10025')
1553
 
        self._check_default_password_prompt(
 
1449
        self._check_default_prompt('SMTP %(user)s@%(host)s password: ',
 
1450
                                   'smtp')
 
1451
        self._check_default_prompt('SMTP %(user)s@%(host)s password: ',
 
1452
                                   'smtp', host='bar.org:10025')
 
1453
        self._check_default_prompt(
1554
1454
            'SMTP %(user)s@%(host)s:%(port)d password: ',
1555
1455
            'smtp', port=10025)
1556
1456
 
1565
1465
"""))
1566
1466
        entered_password = 'typed-by-hand'
1567
1467
        stdout = tests.StringIOWrapper()
1568
 
        stderr = tests.StringIOWrapper()
1569
1468
        ui.ui_factory = tests.TestUIFactory(stdin=entered_password + '\n',
1570
 
                                            stdout=stdout, stderr=stderr)
 
1469
                                            stdout=stdout)
1571
1470
 
1572
1471
        # Since the password defined in the authentication config is ignored,
1573
1472
        # the user is prompted
1587
1486
"""))
1588
1487
        entered_password = 'typed-by-hand'
1589
1488
        stdout = tests.StringIOWrapper()
1590
 
        stderr = tests.StringIOWrapper()
1591
1489
        ui.ui_factory = tests.TestUIFactory(stdin=entered_password + '\n',
1592
 
                                            stdout=stdout,
1593
 
                                            stderr=stderr)
 
1490
                                            stdout=stdout)
1594
1491
 
1595
1492
        # Since the password defined in the authentication config is ignored,
1596
1493
        # the user is prompted
1602
1499
            self._get_log(keep_log_file=True),
1603
1500
            'password ignored in section \[ssh with password\]')
1604
1501
 
1605
 
    def test_uses_fallback_stores(self):
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()
1611
 
        store = StubCredentialStore()
1612
 
        store.add_credentials("http", "example.com", "joe", "secret")
1613
 
        config.credential_store_registry.register("stub", store, fallback=True)
1614
 
        conf = config.AuthenticationConfig(_file=StringIO())
1615
 
        creds = conf.get_credentials("http", "example.com")
1616
 
        self.assertEquals("joe", creds["user"])
1617
 
        self.assertEquals("secret", creds["password"])
1618
 
 
1619
 
 
1620
 
class StubCredentialStore(config.CredentialStore):
1621
 
 
1622
 
    def __init__(self):
1623
 
        self._username = {}
1624
 
        self._password = {}
1625
 
 
1626
 
    def add_credentials(self, scheme, host, user, password=None):
1627
 
        self._username[(scheme, host)] = user
1628
 
        self._password[(scheme, host)] = password
1629
 
 
1630
 
    def get_credentials(self, scheme, host, port=None, user=None,
1631
 
        path=None, realm=None):
1632
 
        key = (scheme, host)
1633
 
        if not key in self._username:
1634
 
            return None
1635
 
        return { "scheme": scheme, "host": host, "port": port,
1636
 
                "user": self._username[key], "password": self._password[key]}
1637
 
 
1638
 
 
1639
 
class CountingCredentialStore(config.CredentialStore):
1640
 
 
1641
 
    def __init__(self):
1642
 
        self._calls = 0
1643
 
 
1644
 
    def get_credentials(self, scheme, host, port=None, user=None,
1645
 
        path=None, realm=None):
1646
 
        self._calls += 1
1647
 
        return None
1648
 
 
1649
 
 
1650
 
class TestCredentialStoreRegistry(tests.TestCase):
1651
 
 
1652
 
    def _get_cs_registry(self):
1653
 
        return config.credential_store_registry
1654
 
 
1655
 
    def test_default_credential_store(self):
1656
 
        r = self._get_cs_registry()
1657
 
        default = r.get_credential_store(None)
1658
 
        self.assertIsInstance(default, config.PlainTextCredentialStore)
1659
 
 
1660
 
    def test_unknown_credential_store(self):
1661
 
        r = self._get_cs_registry()
1662
 
        # It's hard to imagine someone creating a credential store named
1663
 
        # 'unknown' so we use that as an never registered key.
1664
 
        self.assertRaises(KeyError, r.get_credential_store, 'unknown')
1665
 
 
1666
 
    def test_fallback_none_registered(self):
1667
 
        r = config.CredentialStoreRegistry()
1668
 
        self.assertEquals(None,
1669
 
                          r.get_fallback_credentials("http", "example.com"))
1670
 
 
1671
 
    def test_register(self):
1672
 
        r = config.CredentialStoreRegistry()
1673
 
        r.register("stub", StubCredentialStore(), fallback=False)
1674
 
        r.register("another", StubCredentialStore(), fallback=True)
1675
 
        self.assertEquals(["another", "stub"], r.keys())
1676
 
 
1677
 
    def test_register_lazy(self):
1678
 
        r = config.CredentialStoreRegistry()
1679
 
        r.register_lazy("stub", "bzrlib.tests.test_config",
1680
 
                        "StubCredentialStore", fallback=False)
1681
 
        self.assertEquals(["stub"], r.keys())
1682
 
        self.assertIsInstance(r.get_credential_store("stub"),
1683
 
                              StubCredentialStore)
1684
 
 
1685
 
    def test_is_fallback(self):
1686
 
        r = config.CredentialStoreRegistry()
1687
 
        r.register("stub1", None, fallback=False)
1688
 
        r.register("stub2", None, fallback=True)
1689
 
        self.assertEquals(False, r.is_fallback("stub1"))
1690
 
        self.assertEquals(True, r.is_fallback("stub2"))
1691
 
 
1692
 
    def test_no_fallback(self):
1693
 
        r = config.CredentialStoreRegistry()
1694
 
        store = CountingCredentialStore()
1695
 
        r.register("count", store, fallback=False)
1696
 
        self.assertEquals(None,
1697
 
                          r.get_fallback_credentials("http", "example.com"))
1698
 
        self.assertEquals(0, store._calls)
1699
 
 
1700
 
    def test_fallback_credentials(self):
1701
 
        r = config.CredentialStoreRegistry()
1702
 
        store = StubCredentialStore()
1703
 
        store.add_credentials("http", "example.com",
1704
 
                              "somebody", "geheim")
1705
 
        r.register("stub", store, fallback=True)
1706
 
        creds = r.get_fallback_credentials("http", "example.com")
1707
 
        self.assertEquals("somebody", creds["user"])
1708
 
        self.assertEquals("geheim", creds["password"])
1709
 
 
1710
 
    def test_fallback_first_wins(self):
1711
 
        r = config.CredentialStoreRegistry()
1712
 
        stub1 = StubCredentialStore()
1713
 
        stub1.add_credentials("http", "example.com",
1714
 
                              "somebody", "stub1")
1715
 
        r.register("stub1", stub1, fallback=True)
1716
 
        stub2 = StubCredentialStore()
1717
 
        stub2.add_credentials("http", "example.com",
1718
 
                              "somebody", "stub2")
1719
 
        r.register("stub2", stub1, fallback=True)
1720
 
        creds = r.get_fallback_credentials("http", "example.com")
1721
 
        self.assertEquals("somebody", creds["user"])
1722
 
        self.assertEquals("stub1", creds["password"])
1723
 
 
1724
 
 
1725
 
class TestPlainTextCredentialStore(tests.TestCase):
1726
 
 
1727
 
    def test_decode_password(self):
1728
 
        r = config.credential_store_registry
1729
 
        plain_text = r.get_credential_store()
1730
 
        decoded = plain_text.decode_password(dict(password='secret'))
1731
 
        self.assertEquals('secret', decoded)
1732
 
 
1733
1502
 
1734
1503
# FIXME: Once we have a way to declare authentication to all test servers, we
1735
1504
# can implement generic tests.