~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-04-08 06:17:41 UTC
  • mfrom: (4797.33.16 apport)
  • Revision ID: pqm@pqm.ubuntu.com-20100408061741-m7vl6z97vu33riv7
(robertc) Make sure ExecutablePath and InterpreterPath are set in
        Apport. (Martin Pool, James Westby, lp:528114)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 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
13
12
#
14
13
# You should have received a copy of the GNU General Public License
15
14
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
16
 
18
17
"""Tests for finding and reading the bzr config file[s]."""
19
18
# import system imports here
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
        self.assertIs(None, get_bool('an_invalid_bool'))
 
410
        self.assertIs(None, get_bool('not_defined_in_this_config'))
 
411
 
 
412
 
 
413
    def test_get_user_option_as_list(self):
 
414
        conf, parser = self.make_config_parser("""
 
415
a_list = a,b,c
 
416
length_1 = 1,
 
417
one_item = x
 
418
""")
 
419
        get_list = conf.get_user_option_as_list
 
420
        self.assertEqual(['a', 'b', 'c'], get_list('a_list'))
 
421
        self.assertEqual(['1'], get_list('length_1'))
 
422
        self.assertEqual('x', conf.get_user_option('one_item'))
 
423
        # automatically cast to list
 
424
        self.assertEqual(['x'], get_list('one_item'))
 
425
 
 
426
 
 
427
class TestSupressWarning(TestIniConfig):
 
428
 
 
429
    def make_warnings_config(self, s):
 
430
        conf, parser = self.make_config_parser(s)
 
431
        return conf.suppress_warning
 
432
 
 
433
    def test_suppress_warning_unknown(self):
 
434
        suppress_warning = self.make_warnings_config('')
 
435
        self.assertEqual(False, suppress_warning('unknown_warning'))
 
436
 
 
437
    def test_suppress_warning_known(self):
 
438
        suppress_warning = self.make_warnings_config('suppress_warnings=a,b')
 
439
        self.assertEqual(False, suppress_warning('c'))
 
440
        self.assertEqual(True, suppress_warning('a'))
 
441
        self.assertEqual(True, suppress_warning('b'))
 
442
 
 
443
 
368
444
class TestGetConfig(tests.TestCase):
369
445
 
370
446
    def test_constructs(self):
425
501
        locations = config.locations_config_filename()
426
502
        config.ensure_config_dir_exists()
427
503
        local_url = urlutils.local_path_to_url('branch')
428
 
        open(locations, 'wb').write('[%s]\nnickname = foobar' 
 
504
        open(locations, 'wb').write('[%s]\nnickname = foobar'
429
505
                                    % (local_url,))
430
506
        self.assertEqual('foobar', branch.nick)
431
507
 
436
512
 
437
513
        locations = config.locations_config_filename()
438
514
        config.ensure_config_dir_exists()
439
 
        open(locations, 'wb').write('[%s/branch]\nnickname = barry' 
 
515
        open(locations, 'wb').write('[%s/branch]\nnickname = barry'
440
516
                                    % (osutils.getcwd().encode('utf8'),))
441
517
        self.assertEqual('barry', branch.nick)
442
518
 
604
680
        my_config = self._get_sample_config()
605
681
        self.assertEqual(sample_long_alias, my_config.get_alias('ll'))
606
682
 
 
683
    def test_get_change_editor(self):
 
684
        my_config = self._get_sample_config()
 
685
        change_editor = my_config.get_change_editor('old', 'new')
 
686
        self.assertIs(diff.DiffFromTool, change_editor.__class__)
 
687
        self.assertEqual('vimdiff -of @new_path @old_path',
 
688
                         ' '.join(change_editor.command_template))
 
689
 
 
690
    def test_get_no_change_editor(self):
 
691
        my_config = self._get_empty_config()
 
692
        change_editor = my_config.get_change_editor('old', 'new')
 
693
        self.assertIs(None, change_editor)
 
694
 
607
695
 
608
696
class TestGlobalConfigSavingOptions(tests.TestCaseInTempDir):
609
697
 
1207
1295
 
1208
1296
    def test_set_unset_default_stack_on(self):
1209
1297
        my_dir = self.make_bzrdir('.')
1210
 
        bzrdir_config = config.BzrDirConfig(my_dir.transport)
 
1298
        bzrdir_config = config.BzrDirConfig(my_dir)
1211
1299
        self.assertIs(None, bzrdir_config.get_default_stack_on())
1212
1300
        bzrdir_config.set_default_stack_on('Foo')
1213
1301
        self.assertEqual('Foo', bzrdir_config._config.get_option(
1263
1351
"""))
1264
1352
        self.assertRaises(ValueError, conf.get_credentials, 'ftp', 'foo.net')
1265
1353
 
 
1354
    def test_unknown_password_encoding(self):
 
1355
        conf = config.AuthenticationConfig(_file=StringIO(
 
1356
                """[broken]
 
1357
scheme=ftp
 
1358
user=joe
 
1359
password_encoding=unknown
 
1360
"""))
 
1361
        self.assertRaises(ValueError, conf.get_password,
 
1362
                          'ftp', 'foo.net', 'joe')
 
1363
 
1266
1364
    def test_credentials_for_scheme_host(self):
1267
1365
        conf = config.AuthenticationConfig(_file=StringIO(
1268
1366
                """# Identity on foo.net
1412
1510
        self.assertEquals(True, credentials.get('verify_certificates'))
1413
1511
 
1414
1512
 
 
1513
class TestAuthenticationStorage(tests.TestCaseInTempDir):
 
1514
 
 
1515
    def test_set_credentials(self):
 
1516
        conf = config.AuthenticationConfig()
 
1517
        conf.set_credentials('name', 'host', 'user', 'scheme', 'password',
 
1518
        99, path='/foo', verify_certificates=False, realm='realm')
 
1519
        credentials = conf.get_credentials(host='host', scheme='scheme',
 
1520
                                           port=99, path='/foo',
 
1521
                                           realm='realm')
 
1522
        CREDENTIALS = {'name': 'name', 'user': 'user', 'password': 'password',
 
1523
                       'verify_certificates': False, 'scheme': 'scheme', 
 
1524
                       'host': 'host', 'port': 99, 'path': '/foo', 
 
1525
                       'realm': 'realm'}
 
1526
        self.assertEqual(CREDENTIALS, credentials)
 
1527
        credentials_from_disk = config.AuthenticationConfig().get_credentials(
 
1528
            host='host', scheme='scheme', port=99, path='/foo', realm='realm')
 
1529
        self.assertEqual(CREDENTIALS, credentials_from_disk)
 
1530
 
 
1531
    def test_reset_credentials_different_name(self):
 
1532
        conf = config.AuthenticationConfig()
 
1533
        conf.set_credentials('name', 'host', 'user', 'scheme', 'password'),
 
1534
        conf.set_credentials('name2', 'host', 'user2', 'scheme', 'password'),
 
1535
        self.assertIs(None, conf._get_config().get('name'))
 
1536
        credentials = conf.get_credentials(host='host', scheme='scheme')
 
1537
        CREDENTIALS = {'name': 'name2', 'user': 'user2', 'password':
 
1538
                       'password', 'verify_certificates': True, 
 
1539
                       'scheme': 'scheme', 'host': 'host', 'port': None, 
 
1540
                       'path': None, 'realm': None}
 
1541
        self.assertEqual(CREDENTIALS, credentials)
 
1542
 
 
1543
 
1415
1544
class TestAuthenticationConfig(tests.TestCase):
1416
1545
    """Test AuthenticationConfig behaviour"""
1417
1546
 
1418
 
    def _check_default_prompt(self, expected_prompt_format, scheme,
1419
 
                              host=None, port=None, realm=None, path=None):
 
1547
    def _check_default_password_prompt(self, expected_prompt_format, scheme,
 
1548
                                       host=None, port=None, realm=None,
 
1549
                                       path=None):
1420
1550
        if host is None:
1421
1551
            host = 'bar.org'
1422
1552
        user, password = 'jim', 'precious'
1425
1555
            'user': user, 'realm': realm}
1426
1556
 
1427
1557
        stdout = tests.StringIOWrapper()
 
1558
        stderr = tests.StringIOWrapper()
1428
1559
        ui.ui_factory = tests.TestUIFactory(stdin=password + '\n',
1429
 
                                            stdout=stdout)
 
1560
                                            stdout=stdout, stderr=stderr)
1430
1561
        # We use an empty conf so that the user is always prompted
1431
1562
        conf = config.AuthenticationConfig()
1432
1563
        self.assertEquals(password,
1433
1564
                          conf.get_password(scheme, host, user, port=port,
1434
1565
                                            realm=realm, path=path))
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)
 
1566
        self.assertEquals(expected_prompt, stderr.getvalue())
 
1567
        self.assertEquals('', stdout.getvalue())
 
1568
 
 
1569
    def _check_default_username_prompt(self, expected_prompt_format, scheme,
 
1570
                                       host=None, port=None, realm=None,
 
1571
                                       path=None):
 
1572
        if host is None:
 
1573
            host = 'bar.org'
 
1574
        username = 'jim'
 
1575
        expected_prompt = expected_prompt_format % {
 
1576
            'scheme': scheme, 'host': host, 'port': port,
 
1577
            'realm': realm}
 
1578
        stdout = tests.StringIOWrapper()
 
1579
        stderr = tests.StringIOWrapper()
 
1580
        ui.ui_factory = tests.TestUIFactory(stdin=username+ '\n',
 
1581
                                            stdout=stdout, stderr=stderr)
 
1582
        # We use an empty conf so that the user is always prompted
 
1583
        conf = config.AuthenticationConfig()
 
1584
        self.assertEquals(username, conf.get_user(scheme, host, port=port,
 
1585
                          realm=realm, path=path, ask=True))
 
1586
        self.assertEquals(expected_prompt, stderr.getvalue())
 
1587
        self.assertEquals('', stdout.getvalue())
 
1588
 
 
1589
    def test_username_defaults_prompts(self):
 
1590
        # HTTP prompts can't be tested here, see test_http.py
 
1591
        self._check_default_username_prompt('FTP %(host)s username: ', 'ftp')
 
1592
        self._check_default_username_prompt(
 
1593
            'FTP %(host)s:%(port)d username: ', 'ftp', port=10020)
 
1594
        self._check_default_username_prompt(
 
1595
            'SSH %(host)s:%(port)d username: ', 'ssh', port=12345)
 
1596
 
 
1597
    def test_username_default_no_prompt(self):
 
1598
        conf = config.AuthenticationConfig()
 
1599
        self.assertEquals(None,
 
1600
            conf.get_user('ftp', 'example.com'))
 
1601
        self.assertEquals("explicitdefault",
 
1602
            conf.get_user('ftp', 'example.com', default="explicitdefault"))
 
1603
 
 
1604
    def test_password_default_prompts(self):
 
1605
        # HTTP prompts can't be tested here, see test_http.py
 
1606
        self._check_default_password_prompt(
 
1607
            'FTP %(user)s@%(host)s password: ', 'ftp')
 
1608
        self._check_default_password_prompt(
 
1609
            'FTP %(user)s@%(host)s:%(port)d password: ', 'ftp', port=10020)
 
1610
        self._check_default_password_prompt(
 
1611
            'SSH %(user)s@%(host)s:%(port)d password: ', 'ssh', port=12345)
1445
1612
        # SMTP port handling is a bit special (it's handled if embedded in the
1446
1613
        # host too)
1447
1614
        # FIXME: should we: forbid that, extend it to other schemes, leave
1448
1615
        # things as they are that's fine thank you ?
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(
 
1616
        self._check_default_password_prompt('SMTP %(user)s@%(host)s password: ',
 
1617
                                            'smtp')
 
1618
        self._check_default_password_prompt('SMTP %(user)s@%(host)s password: ',
 
1619
                                            'smtp', host='bar.org:10025')
 
1620
        self._check_default_password_prompt(
1454
1621
            'SMTP %(user)s@%(host)s:%(port)d password: ',
1455
1622
            'smtp', port=10025)
1456
1623
 
1465
1632
"""))
1466
1633
        entered_password = 'typed-by-hand'
1467
1634
        stdout = tests.StringIOWrapper()
 
1635
        stderr = tests.StringIOWrapper()
1468
1636
        ui.ui_factory = tests.TestUIFactory(stdin=entered_password + '\n',
1469
 
                                            stdout=stdout)
 
1637
                                            stdout=stdout, stderr=stderr)
1470
1638
 
1471
1639
        # Since the password defined in the authentication config is ignored,
1472
1640
        # the user is prompted
1473
1641
        self.assertEquals(entered_password,
1474
1642
                          conf.get_password('ssh', 'bar.org', user='jim'))
1475
1643
        self.assertContainsRe(
1476
 
            self._get_log(keep_log_file=True),
 
1644
            self.get_log(),
1477
1645
            'password ignored in section \[ssh with password\]')
1478
1646
 
1479
1647
    def test_ssh_without_password_doesnt_emit_warning(self):
1486
1654
"""))
1487
1655
        entered_password = 'typed-by-hand'
1488
1656
        stdout = tests.StringIOWrapper()
 
1657
        stderr = tests.StringIOWrapper()
1489
1658
        ui.ui_factory = tests.TestUIFactory(stdin=entered_password + '\n',
1490
 
                                            stdout=stdout)
 
1659
                                            stdout=stdout,
 
1660
                                            stderr=stderr)
1491
1661
 
1492
1662
        # Since the password defined in the authentication config is ignored,
1493
1663
        # the user is prompted
1496
1666
        # No warning shoud be emitted since there is no password. We are only
1497
1667
        # providing "user".
1498
1668
        self.assertNotContainsRe(
1499
 
            self._get_log(keep_log_file=True),
 
1669
            self.get_log(),
1500
1670
            'password ignored in section \[ssh with password\]')
1501
1671
 
 
1672
    def test_uses_fallback_stores(self):
 
1673
        self.overrideAttr(config, 'credential_store_registry',
 
1674
                          config.CredentialStoreRegistry())
 
1675
        store = StubCredentialStore()
 
1676
        store.add_credentials("http", "example.com", "joe", "secret")
 
1677
        config.credential_store_registry.register("stub", store, fallback=True)
 
1678
        conf = config.AuthenticationConfig(_file=StringIO())
 
1679
        creds = conf.get_credentials("http", "example.com")
 
1680
        self.assertEquals("joe", creds["user"])
 
1681
        self.assertEquals("secret", creds["password"])
 
1682
 
 
1683
 
 
1684
class StubCredentialStore(config.CredentialStore):
 
1685
 
 
1686
    def __init__(self):
 
1687
        self._username = {}
 
1688
        self._password = {}
 
1689
 
 
1690
    def add_credentials(self, scheme, host, user, password=None):
 
1691
        self._username[(scheme, host)] = user
 
1692
        self._password[(scheme, host)] = password
 
1693
 
 
1694
    def get_credentials(self, scheme, host, port=None, user=None,
 
1695
        path=None, realm=None):
 
1696
        key = (scheme, host)
 
1697
        if not key in self._username:
 
1698
            return None
 
1699
        return { "scheme": scheme, "host": host, "port": port,
 
1700
                "user": self._username[key], "password": self._password[key]}
 
1701
 
 
1702
 
 
1703
class CountingCredentialStore(config.CredentialStore):
 
1704
 
 
1705
    def __init__(self):
 
1706
        self._calls = 0
 
1707
 
 
1708
    def get_credentials(self, scheme, host, port=None, user=None,
 
1709
        path=None, realm=None):
 
1710
        self._calls += 1
 
1711
        return None
 
1712
 
 
1713
 
 
1714
class TestCredentialStoreRegistry(tests.TestCase):
 
1715
 
 
1716
    def _get_cs_registry(self):
 
1717
        return config.credential_store_registry
 
1718
 
 
1719
    def test_default_credential_store(self):
 
1720
        r = self._get_cs_registry()
 
1721
        default = r.get_credential_store(None)
 
1722
        self.assertIsInstance(default, config.PlainTextCredentialStore)
 
1723
 
 
1724
    def test_unknown_credential_store(self):
 
1725
        r = self._get_cs_registry()
 
1726
        # It's hard to imagine someone creating a credential store named
 
1727
        # 'unknown' so we use that as an never registered key.
 
1728
        self.assertRaises(KeyError, r.get_credential_store, 'unknown')
 
1729
 
 
1730
    def test_fallback_none_registered(self):
 
1731
        r = config.CredentialStoreRegistry()
 
1732
        self.assertEquals(None,
 
1733
                          r.get_fallback_credentials("http", "example.com"))
 
1734
 
 
1735
    def test_register(self):
 
1736
        r = config.CredentialStoreRegistry()
 
1737
        r.register("stub", StubCredentialStore(), fallback=False)
 
1738
        r.register("another", StubCredentialStore(), fallback=True)
 
1739
        self.assertEquals(["another", "stub"], r.keys())
 
1740
 
 
1741
    def test_register_lazy(self):
 
1742
        r = config.CredentialStoreRegistry()
 
1743
        r.register_lazy("stub", "bzrlib.tests.test_config",
 
1744
                        "StubCredentialStore", fallback=False)
 
1745
        self.assertEquals(["stub"], r.keys())
 
1746
        self.assertIsInstance(r.get_credential_store("stub"),
 
1747
                              StubCredentialStore)
 
1748
 
 
1749
    def test_is_fallback(self):
 
1750
        r = config.CredentialStoreRegistry()
 
1751
        r.register("stub1", None, fallback=False)
 
1752
        r.register("stub2", None, fallback=True)
 
1753
        self.assertEquals(False, r.is_fallback("stub1"))
 
1754
        self.assertEquals(True, r.is_fallback("stub2"))
 
1755
 
 
1756
    def test_no_fallback(self):
 
1757
        r = config.CredentialStoreRegistry()
 
1758
        store = CountingCredentialStore()
 
1759
        r.register("count", store, fallback=False)
 
1760
        self.assertEquals(None,
 
1761
                          r.get_fallback_credentials("http", "example.com"))
 
1762
        self.assertEquals(0, store._calls)
 
1763
 
 
1764
    def test_fallback_credentials(self):
 
1765
        r = config.CredentialStoreRegistry()
 
1766
        store = StubCredentialStore()
 
1767
        store.add_credentials("http", "example.com",
 
1768
                              "somebody", "geheim")
 
1769
        r.register("stub", store, fallback=True)
 
1770
        creds = r.get_fallback_credentials("http", "example.com")
 
1771
        self.assertEquals("somebody", creds["user"])
 
1772
        self.assertEquals("geheim", creds["password"])
 
1773
 
 
1774
    def test_fallback_first_wins(self):
 
1775
        r = config.CredentialStoreRegistry()
 
1776
        stub1 = StubCredentialStore()
 
1777
        stub1.add_credentials("http", "example.com",
 
1778
                              "somebody", "stub1")
 
1779
        r.register("stub1", stub1, fallback=True)
 
1780
        stub2 = StubCredentialStore()
 
1781
        stub2.add_credentials("http", "example.com",
 
1782
                              "somebody", "stub2")
 
1783
        r.register("stub2", stub1, fallback=True)
 
1784
        creds = r.get_fallback_credentials("http", "example.com")
 
1785
        self.assertEquals("somebody", creds["user"])
 
1786
        self.assertEquals("stub1", creds["password"])
 
1787
 
 
1788
 
 
1789
class TestPlainTextCredentialStore(tests.TestCase):
 
1790
 
 
1791
    def test_decode_password(self):
 
1792
        r = config.credential_store_registry
 
1793
        plain_text = r.get_credential_store()
 
1794
        decoded = plain_text.decode_password(dict(password='secret'))
 
1795
        self.assertEquals('secret', decoded)
 
1796
 
1502
1797
 
1503
1798
# FIXME: Once we have a way to declare authentication to all test servers, we
1504
1799
# can implement generic tests.