~ubuntu-branches/ubuntu/trusty/python3.4/trusty-proposed

« back to all changes in this revision

Viewing changes to Lib/test/test_getpass.py

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-11-25 09:44:27 UTC
  • Revision ID: package-import@ubuntu.com-20131125094427-lzxj8ap5w01lmo7f
Tags: upstream-3.4~b1
ImportĀ upstreamĀ versionĀ 3.4~b1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import getpass
 
2
import os
 
3
import unittest
 
4
from io import BytesIO, StringIO
 
5
from unittest import mock
 
6
from test import support
 
7
 
 
8
try:
 
9
    import termios
 
10
except ImportError:
 
11
    termios = None
 
12
try:
 
13
    import pwd
 
14
except ImportError:
 
15
    pwd = None
 
16
 
 
17
@mock.patch('os.environ')
 
18
class GetpassGetuserTest(unittest.TestCase):
 
19
 
 
20
    def test_username_takes_username_from_env(self, environ):
 
21
        expected_name = 'some_name'
 
22
        environ.get.return_value = expected_name
 
23
        self.assertEqual(expected_name, getpass.getuser())
 
24
 
 
25
    def test_username_priorities_of_env_values(self, environ):
 
26
        environ.get.return_value = None
 
27
        try:
 
28
            getpass.getuser()
 
29
        except ImportError: # in case there's no pwd module
 
30
            pass
 
31
        self.assertEqual(
 
32
            environ.get.call_args_list,
 
33
            [mock.call(x) for x in ('LOGNAME', 'USER', 'LNAME', 'USERNAME')])
 
34
 
 
35
    def test_username_falls_back_to_pwd(self, environ):
 
36
        expected_name = 'some_name'
 
37
        environ.get.return_value = None
 
38
        if pwd:
 
39
            with mock.patch('os.getuid') as uid, \
 
40
                    mock.patch('pwd.getpwuid') as getpw:
 
41
                uid.return_value = 42
 
42
                getpw.return_value = [expected_name]
 
43
                self.assertEqual(expected_name,
 
44
                                 getpass.getuser())
 
45
                getpw.assert_called_once_with(42)
 
46
        else:
 
47
            self.assertRaises(ImportError, getpass.getuser)
 
48
 
 
49
 
 
50
class GetpassRawinputTest(unittest.TestCase):
 
51
 
 
52
    def test_flushes_stream_after_prompt(self):
 
53
        # see issue 1703
 
54
        stream = mock.Mock(spec=StringIO)
 
55
        input = StringIO('input_string')
 
56
        getpass._raw_input('some_prompt', stream, input=input)
 
57
        stream.flush.assert_called_once_with()
 
58
 
 
59
    def test_uses_stderr_as_default(self):
 
60
        input = StringIO('input_string')
 
61
        prompt = 'some_prompt'
 
62
        with mock.patch('sys.stderr') as stderr:
 
63
            getpass._raw_input(prompt, input=input)
 
64
            stderr.write.assert_called_once_with(prompt)
 
65
 
 
66
    @mock.patch('sys.stdin')
 
67
    def test_uses_stdin_as_default_input(self, mock_input):
 
68
        mock_input.readline.return_value = 'input_string'
 
69
        getpass._raw_input(stream=StringIO())
 
70
        mock_input.readline.assert_called_once_with()
 
71
 
 
72
    def test_raises_on_empty_input(self):
 
73
        input = StringIO('')
 
74
        self.assertRaises(EOFError, getpass._raw_input, input=input)
 
75
 
 
76
    def test_trims_trailing_newline(self):
 
77
        input = StringIO('test\n')
 
78
        self.assertEqual('test', getpass._raw_input(input=input))
 
79
 
 
80
 
 
81
# Some of these tests are a bit white-box.  The functional requirement is that
 
82
# the password input be taken directly from the tty, and that it not be echoed
 
83
# on the screen, unless we are falling back to stderr/stdin.
 
84
 
 
85
# Some of these might run on platforms without termios, but play it safe.
 
86
@unittest.skipUnless(termios, 'tests require system with termios')
 
87
class UnixGetpassTest(unittest.TestCase):
 
88
 
 
89
    def test_uses_tty_directly(self):
 
90
        with mock.patch('os.open') as open, \
 
91
                mock.patch('io.FileIO') as fileio, \
 
92
                mock.patch('io.TextIOWrapper') as textio:
 
93
            # By setting open's return value to None the implementation will
 
94
            # skip code we don't care about in this test.  We can mock this out
 
95
            # fully if an alternate implementation works differently.
 
96
            open.return_value = None
 
97
            getpass.unix_getpass()
 
98
            open.assert_called_once_with('/dev/tty',
 
99
                                         os.O_RDWR | os.O_NOCTTY)
 
100
            fileio.assert_called_once_with(open.return_value, 'w+')
 
101
            textio.assert_called_once_with(fileio.return_value)
 
102
 
 
103
    def test_resets_termios(self):
 
104
        with mock.patch('os.open') as open, \
 
105
                mock.patch('io.FileIO'), \
 
106
                mock.patch('io.TextIOWrapper'), \
 
107
                mock.patch('termios.tcgetattr') as tcgetattr, \
 
108
                mock.patch('termios.tcsetattr') as tcsetattr:
 
109
            open.return_value = 3
 
110
            fake_attrs = [255, 255, 255, 255, 255]
 
111
            tcgetattr.return_value = list(fake_attrs)
 
112
            getpass.unix_getpass()
 
113
            tcsetattr.assert_called_with(3, mock.ANY, fake_attrs)
 
114
 
 
115
    def test_falls_back_to_fallback_if_termios_raises(self):
 
116
        with mock.patch('os.open') as open, \
 
117
                mock.patch('io.FileIO') as fileio, \
 
118
                mock.patch('io.TextIOWrapper') as textio, \
 
119
                mock.patch('termios.tcgetattr'), \
 
120
                mock.patch('termios.tcsetattr') as tcsetattr, \
 
121
                mock.patch('getpass.fallback_getpass') as fallback:
 
122
            open.return_value = 3
 
123
            fileio.return_value = BytesIO()
 
124
            tcsetattr.side_effect = termios.error
 
125
            getpass.unix_getpass()
 
126
            fallback.assert_called_once_with('Password: ',
 
127
                                             textio.return_value)
 
128
 
 
129
    def test_flushes_stream_after_input(self):
 
130
        # issue 7208
 
131
        with mock.patch('os.open') as open, \
 
132
                mock.patch('io.FileIO'), \
 
133
                mock.patch('io.TextIOWrapper'), \
 
134
                mock.patch('termios.tcgetattr'), \
 
135
                mock.patch('termios.tcsetattr'):
 
136
            open.return_value = 3
 
137
            mock_stream = mock.Mock(spec=StringIO)
 
138
            getpass.unix_getpass(stream=mock_stream)
 
139
            mock_stream.flush.assert_called_with()
 
140
 
 
141
    def test_falls_back_to_stdin(self):
 
142
        with mock.patch('os.open') as os_open, \
 
143
                mock.patch('sys.stdin', spec=StringIO) as stdin:
 
144
            os_open.side_effect = IOError
 
145
            stdin.fileno.side_effect = AttributeError
 
146
            with support.captured_stderr() as stderr:
 
147
                with self.assertWarns(getpass.GetPassWarning):
 
148
                    getpass.unix_getpass()
 
149
            stdin.readline.assert_called_once_with()
 
150
            self.assertIn('Warning', stderr.getvalue())
 
151
            self.assertIn('Password:', stderr.getvalue())
 
152
 
 
153
 
 
154
if __name__ == "__main__":
 
155
    unittest.main()