/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_config.py

  • Committer: Andrew Bennetts
  • Date: 2008-08-12 14:53:26 UTC
  • mto: This revision was merged to the branch mainline in revision 3624.
  • Revision ID: andrew.bennetts@canonical.com-20080812145326-yx693x2jc4rcovb7
Move the notes on writing tests out of HACKING into a new file, and improve
them.

Many of the testing notes in the HACKING file were in duplicated in two places
in that file!  This change removes that duplication.  It also adds new sections
on “Where should I put a new test?” and “TestCase and its subclasses”, and
others like “Test feature dependencies” have been expanded.  The whole document
has generally been edited to be a bit more coherent. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 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
25
26
    branch,
26
27
    bzrdir,
27
28
    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
47
46
gpg_signing_command=gnome-gpg
48
47
log_format=short
49
48
user_global_option=something
151
150
        self._transport = self.control_files = \
152
151
            FakeControlFilesAndTransport(user_id=user_id)
153
152
 
154
 
    def _get_config(self):
155
 
        return config.TransportConfig(self._transport, 'branch.conf')
156
 
 
157
153
    def lock_write(self):
158
154
        pass
159
155
 
210
206
        self._calls.append('_get_signature_checking')
211
207
        return self._signatures
212
208
 
213
 
    def _get_change_editor(self):
214
 
        self._calls.append('_get_change_editor')
215
 
        return 'vimdiff -fo @new_path @old_path'
216
 
 
217
209
 
218
210
bool_config = """[DEFAULT]
219
211
active = true
320
312
        my_config = config.Config()
321
313
        self.assertEqual('long', my_config.log_format())
322
314
 
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
 
 
331
315
 
332
316
class TestConfigPath(tests.TestCase):
333
317
 
334
318
    def setUp(self):
335
319
        super(TestConfigPath, self).setUp()
336
320
        os.environ['HOME'] = '/home/bogus'
337
 
        os.environ['XDG_CACHE_DIR'] = ''
338
321
        if sys.platform == 'win32':
339
322
            os.environ['BZR_HOME'] = \
340
323
                r'C:\Documents and Settings\bogus\Application Data'
362
345
        self.assertEqual(config.authentication_config_filename(),
363
346
                         self.bzr_home + '/authentication.conf')
364
347
 
365
 
    def test_xdg_cache_dir(self):
366
 
        self.assertEqual(config.xdg_cache_dir(),
367
 
            '/home/bogus/.cache')
368
 
 
369
348
 
370
349
class TestIniConfig(tests.TestCase):
371
350
 
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
 
 
380
351
    def test_contructs(self):
381
352
        my_config = config.IniBasedConfig("nothing")
382
353
 
394
365
        self.failUnless(my_config._get_parser() is parser)
395
366
 
396
367
 
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
 
 
451
368
class TestGetConfig(tests.TestCase):
452
369
 
453
370
    def test_constructs(self):
508
425
        locations = config.locations_config_filename()
509
426
        config.ensure_config_dir_exists()
510
427
        local_url = urlutils.local_path_to_url('branch')
511
 
        open(locations, 'wb').write('[%s]\nnickname = foobar'
 
428
        open(locations, 'wb').write('[%s]\nnickname = foobar' 
512
429
                                    % (local_url,))
513
430
        self.assertEqual('foobar', branch.nick)
514
431
 
519
436
 
520
437
        locations = config.locations_config_filename()
521
438
        config.ensure_config_dir_exists()
522
 
        open(locations, 'wb').write('[%s/branch]\nnickname = barry'
 
439
        open(locations, 'wb').write('[%s/branch]\nnickname = barry' 
523
440
                                    % (osutils.getcwd().encode('utf8'),))
524
441
        self.assertEqual('barry', branch.nick)
525
442
 
687
604
        my_config = self._get_sample_config()
688
605
        self.assertEqual(sample_long_alias, my_config.get_alias('ll'))
689
606
 
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
 
 
702
607
 
703
608
class TestGlobalConfigSavingOptions(tests.TestCaseInTempDir):
704
609
 
1046
951
        self.assertIs(self.my_config.get_user_option('foo'), None)
1047
952
        self.my_config.set_user_option('foo', 'bar')
1048
953
        self.assertEqual(
1049
 
            self.my_config.branch.control_files.files['branch.conf'].strip(),
1050
 
            'foo = bar')
 
954
            self.my_config.branch.control_files.files['branch.conf'],
 
955
            'foo = bar\n')
1051
956
        self.assertEqual(self.my_config.get_user_option('foo'), 'bar')
1052
957
        self.my_config.set_user_option('foo', 'baz',
1053
958
                                       store=config.STORE_LOCATION)
1302
1207
 
1303
1208
    def test_set_unset_default_stack_on(self):
1304
1209
        my_dir = self.make_bzrdir('.')
1305
 
        bzrdir_config = config.BzrDirConfig(my_dir)
 
1210
        bzrdir_config = config.BzrDirConfig(my_dir.transport)
1306
1211
        self.assertIs(None, bzrdir_config.get_default_stack_on())
1307
1212
        bzrdir_config.set_default_stack_on('Foo')
1308
1213
        self.assertEqual('Foo', bzrdir_config._config.get_option(
1358
1263
"""))
1359
1264
        self.assertRaises(ValueError, conf.get_credentials, 'ftp', 'foo.net')
1360
1265
 
1361
 
    def test_unknown_password_encoding(self):
1362
 
        conf = config.AuthenticationConfig(_file=StringIO(
1363
 
                """[broken]
1364
 
scheme=ftp
1365
 
user=joe
1366
 
password_encoding=unknown
1367
 
"""))
1368
 
        self.assertRaises(ValueError, conf.get_password,
1369
 
                          'ftp', 'foo.net', 'joe')
1370
 
 
1371
1266
    def test_credentials_for_scheme_host(self):
1372
1267
        conf = config.AuthenticationConfig(_file=StringIO(
1373
1268
                """# Identity on foo.net
1517
1412
        self.assertEquals(True, credentials.get('verify_certificates'))
1518
1413
 
1519
1414
 
1520
 
class TestAuthenticationStorage(tests.TestCaseInTempDir):
1521
 
 
1522
 
    def test_set_credentials(self):
1523
 
        conf = config.AuthenticationConfig()
1524
 
        conf.set_credentials('name', 'host', 'user', 'scheme', 'password',
1525
 
        99, path='/foo', verify_certificates=False, realm='realm')
1526
 
        credentials = conf.get_credentials(host='host', scheme='scheme',
1527
 
                                           port=99, path='/foo',
1528
 
                                           realm='realm')
1529
 
        CREDENTIALS = {'name': 'name', 'user': 'user', 'password': 'password',
1530
 
                       'verify_certificates': False, 'scheme': 'scheme', 
1531
 
                       'host': 'host', 'port': 99, 'path': '/foo', 
1532
 
                       'realm': 'realm'}
1533
 
        self.assertEqual(CREDENTIALS, credentials)
1534
 
        credentials_from_disk = config.AuthenticationConfig().get_credentials(
1535
 
            host='host', scheme='scheme', port=99, path='/foo', realm='realm')
1536
 
        self.assertEqual(CREDENTIALS, credentials_from_disk)
1537
 
 
1538
 
    def test_reset_credentials_different_name(self):
1539
 
        conf = config.AuthenticationConfig()
1540
 
        conf.set_credentials('name', 'host', 'user', 'scheme', 'password'),
1541
 
        conf.set_credentials('name2', 'host', 'user2', 'scheme', 'password'),
1542
 
        self.assertIs(None, conf._get_config().get('name'))
1543
 
        credentials = conf.get_credentials(host='host', scheme='scheme')
1544
 
        CREDENTIALS = {'name': 'name2', 'user': 'user2', 'password':
1545
 
                       'password', 'verify_certificates': True, 
1546
 
                       'scheme': 'scheme', 'host': 'host', 'port': None, 
1547
 
                       'path': None, 'realm': None}
1548
 
        self.assertEqual(CREDENTIALS, credentials)
1549
 
 
1550
 
 
1551
1415
class TestAuthenticationConfig(tests.TestCase):
1552
1416
    """Test AuthenticationConfig behaviour"""
1553
1417
 
1554
 
    def _check_default_password_prompt(self, expected_prompt_format, scheme,
1555
 
                                       host=None, port=None, realm=None,
1556
 
                                       path=None):
 
1418
    def _check_default_prompt(self, expected_prompt_format, scheme,
 
1419
                              host=None, port=None, realm=None, path=None):
1557
1420
        if host is None:
1558
1421
            host = 'bar.org'
1559
1422
        user, password = 'jim', 'precious'
1562
1425
            'user': user, 'realm': realm}
1563
1426
 
1564
1427
        stdout = tests.StringIOWrapper()
1565
 
        stderr = tests.StringIOWrapper()
1566
1428
        ui.ui_factory = tests.TestUIFactory(stdin=password + '\n',
1567
 
                                            stdout=stdout, stderr=stderr)
 
1429
                                            stdout=stdout)
1568
1430
        # We use an empty conf so that the user is always prompted
1569
1431
        conf = config.AuthenticationConfig()
1570
1432
        self.assertEquals(password,
1571
1433
                          conf.get_password(scheme, host, user, port=port,
1572
1434
                                            realm=realm, path=path))
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)
 
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)
1619
1445
        # SMTP port handling is a bit special (it's handled if embedded in the
1620
1446
        # host too)
1621
1447
        # FIXME: should we: forbid that, extend it to other schemes, leave
1622
1448
        # things as they are that's fine thank you ?
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(
 
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(
1628
1454
            'SMTP %(user)s@%(host)s:%(port)d password: ',
1629
1455
            'smtp', port=10025)
1630
1456
 
1639
1465
"""))
1640
1466
        entered_password = 'typed-by-hand'
1641
1467
        stdout = tests.StringIOWrapper()
1642
 
        stderr = tests.StringIOWrapper()
1643
1468
        ui.ui_factory = tests.TestUIFactory(stdin=entered_password + '\n',
1644
 
                                            stdout=stdout, stderr=stderr)
 
1469
                                            stdout=stdout)
1645
1470
 
1646
1471
        # Since the password defined in the authentication config is ignored,
1647
1472
        # the user is prompted
1648
1473
        self.assertEquals(entered_password,
1649
1474
                          conf.get_password('ssh', 'bar.org', user='jim'))
1650
1475
        self.assertContainsRe(
1651
 
            self.get_log(),
 
1476
            self._get_log(keep_log_file=True),
1652
1477
            'password ignored in section \[ssh with password\]')
1653
1478
 
1654
1479
    def test_ssh_without_password_doesnt_emit_warning(self):
1661
1486
"""))
1662
1487
        entered_password = 'typed-by-hand'
1663
1488
        stdout = tests.StringIOWrapper()
1664
 
        stderr = tests.StringIOWrapper()
1665
1489
        ui.ui_factory = tests.TestUIFactory(stdin=entered_password + '\n',
1666
 
                                            stdout=stdout,
1667
 
                                            stderr=stderr)
 
1490
                                            stdout=stdout)
1668
1491
 
1669
1492
        # Since the password defined in the authentication config is ignored,
1670
1493
        # the user is prompted
1673
1496
        # No warning shoud be emitted since there is no password. We are only
1674
1497
        # providing "user".
1675
1498
        self.assertNotContainsRe(
1676
 
            self.get_log(),
 
1499
            self._get_log(keep_log_file=True),
1677
1500
            'password ignored in section \[ssh with password\]')
1678
1501
 
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
 
 
1720
 
 
1721
 
class TestCredentialStoreRegistry(tests.TestCase):
1722
 
 
1723
 
    def _get_cs_registry(self):
1724
 
        return config.credential_store_registry
1725
 
 
1726
 
    def test_default_credential_store(self):
1727
 
        r = self._get_cs_registry()
1728
 
        default = r.get_credential_store(None)
1729
 
        self.assertIsInstance(default, config.PlainTextCredentialStore)
1730
 
 
1731
 
    def test_unknown_credential_store(self):
1732
 
        r = self._get_cs_registry()
1733
 
        # It's hard to imagine someone creating a credential store named
1734
 
        # 'unknown' so we use that as an never registered key.
1735
 
        self.assertRaises(KeyError, r.get_credential_store, 'unknown')
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
 
 
1795
 
 
1796
 
class TestPlainTextCredentialStore(tests.TestCase):
1797
 
 
1798
 
    def test_decode_password(self):
1799
 
        r = config.credential_store_registry
1800
 
        plain_text = r.get_credential_store()
1801
 
        decoded = plain_text.decode_password(dict(password='secret'))
1802
 
        self.assertEquals('secret', decoded)
1803
 
 
1804
1502
 
1805
1503
# FIXME: Once we have a way to declare authentication to all test servers, we
1806
1504
# can implement generic tests.