diff --git a/certbot/display/util.py b/certbot/display/util.py index 7e797e71a..5b01dd8d4 100644 --- a/certbot/display/util.py +++ b/certbot/display/util.py @@ -69,6 +69,8 @@ def input_with_timeout(prompt=None, timeout=36000.0): :raises errors.Error if no answer is given before the timeout """ + # use of sys.stdin and sys.stdout to mimic six.moves.input based on + # https://github.com/python/cpython/blob/baf7bb30a02aabde260143136bdf5b3738a1d409/Lib/getpass.py#L129 if prompt: sys.stdout.write(prompt) sys.stdout.flush() @@ -79,7 +81,10 @@ def input_with_timeout(prompt=None, timeout=36000.0): raise errors.Error( "Timed out waiting for answer to prompt '{0}'".format(prompt)) - return rlist[0].readline().rstrip('\n') + line = rlist[0].readline() + if not line: + raise EOFError + return line.rstrip('\n') @zope.interface.implementer(interfaces.IDisplay) diff --git a/certbot/tests/display/util_test.py b/certbot/tests/display/util_test.py index a872917ec..1dfc21c30 100644 --- a/certbot/tests/display/util_test.py +++ b/certbot/tests/display/util_test.py @@ -2,6 +2,7 @@ import inspect import os import socket +import tempfile import unittest import six @@ -25,15 +26,17 @@ class InputWithTimeoutTest(unittest.TestCase): from certbot.display.util import input_with_timeout return input_with_timeout(*args, **kwargs) - def setUp(self): - self.expected_msg = "foo bar" - self.stdin = six.StringIO(self.expected_msg + "\n") + def test_eof(self): + with tempfile.TemporaryFile("r+") as f: + with mock.patch("certbot.display.util.sys.stdin", new=f): + self.assertRaises(EOFError, self._call) def test_input(self, prompt=None): + expected = "foo bar" + stdin = six.StringIO(expected + "\n") with mock.patch("certbot.display.util.select.select") as mock_select: - mock_select.return_value = ([self.stdin], [], [],) - self.assertEqual(display_util.input_with_timeout(prompt), - self.expected_msg) + mock_select.return_value = ([stdin], [], [],) + self.assertEqual(self._call(prompt), expected) @mock.patch("certbot.display.util.sys.stdout") def test_input_with_prompt(self, mock_stdout):