Skip to content

Commit 0d43164

Browse files
miss-islingtonrudy-07orsenthil
authored
[3.15] gh-131178: Add tests for ftplib command-line interface (GH-161080) (#161154)
* gh-131178: Add tests for ftplib command-line interface Add unit tests in Lib/test/test_ftplib.py covering the ftplib command-line interface: verifying usage message on empty invocation, subprocess invocation, host connection with debuglevel, directory and passive mode commands, file retrieval, and custom netrc file error handling. (cherry picked from commit c29f95a) Co-authored-by: Rudransh Shekhar <kanhaiffco2007@gmail.com> Co-authored-by: Senthil Kumaran <senthil@python.org>
1 parent fe47a43 commit 0d43164

1 file changed

Lines changed: 71 additions & 0 deletions

File tree

‎Lib/test/test_ftplib.py‎

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,6 +1188,77 @@ def test__all__(self):
11881188
support.check__all__(self, ftplib, not_exported=not_exported)
11891189

11901190

1191+
class CommandLineTest(TestCase):
1192+
"""Tests for the ftplib command-line interface."""
1193+
1194+
def test_main_no_arguments_prints_usage(self):
1195+
with mock.patch('sys.argv', ['ftplib']), \
1196+
support.captured_stdout() as stdout:
1197+
with self.assertRaises(SystemExit) as cm:
1198+
ftplib.test()
1199+
self.assertEqual(cm.exception.code, 0)
1200+
output = stdout.getvalue()
1201+
self.assertIn('Usage:', output)
1202+
self.assertIn('Options:', output)
1203+
self.assertIn('Commands:', output)
1204+
1205+
@requires_subprocess()
1206+
def test_subprocess_invocation_no_args(self):
1207+
from test.support.script_helper import assert_python_ok
1208+
rc, out, err = assert_python_ok('-m', 'ftplib')
1209+
self.assertEqual(rc, 0)
1210+
self.assertIn(b'Usage:', out)
1211+
self.assertIn(b'Options:', out)
1212+
self.assertIn(b'Commands:', out)
1213+
self.assertEqual(err, b'')
1214+
1215+
@mock.patch('ftplib.FTP')
1216+
@mock.patch('netrc.netrc', side_effect=OSError)
1217+
def test_cli_host_and_debugging(self, mock_netrc, mock_ftp_cls):
1218+
mock_ftp = mock_ftp_cls.return_value
1219+
with mock.patch('sys.argv', ['ftplib', '-d', '-d', 'example.com']):
1220+
ftplib.test()
1221+
mock_ftp_cls.assert_called_once_with('example.com')
1222+
mock_ftp.set_debuglevel.assert_called_once_with(2)
1223+
mock_ftp.login.assert_called_once_with('', '', '')
1224+
mock_ftp.quit.assert_called_once()
1225+
1226+
@mock.patch('ftplib.FTP')
1227+
@mock.patch('netrc.netrc', side_effect=OSError)
1228+
def test_cli_commands(self, mock_netrc, mock_ftp_cls):
1229+
mock_ftp = mock_ftp_cls.return_value
1230+
with mock.patch('sys.argv', ['ftplib', 'example.com', '-l/pub', '-d/incoming', '-p']):
1231+
ftplib.test()
1232+
mock_ftp_cls.assert_called_once_with('example.com')
1233+
mock_ftp.dir.assert_called_once_with('/pub')
1234+
mock_ftp.sendcmd.assert_called_once_with('CWD /incoming')
1235+
mock_ftp.set_pasv.assert_called_once()
1236+
mock_ftp.quit.assert_called_once()
1237+
1238+
@mock.patch('ftplib.FTP')
1239+
@mock.patch('netrc.netrc', side_effect=OSError)
1240+
def test_cli_retrieve_file(self, mock_netrc, mock_ftp_cls):
1241+
mock_ftp = mock_ftp_cls.return_value
1242+
with mock.patch('sys.argv', ['ftplib', 'example.com', 'testfile.txt']), \
1243+
mock.patch('sys.stdout') as mock_stdout:
1244+
ftplib.test()
1245+
mock_ftp.retrbinary.assert_called_once_with(
1246+
'RETR testfile.txt', mock_stdout.buffer.write, 1024
1247+
)
1248+
mock_stdout.buffer.flush.assert_called_once()
1249+
mock_stdout.flush.assert_called_once()
1250+
mock_ftp.quit.assert_called_once()
1251+
1252+
@mock.patch('ftplib.FTP')
1253+
@mock.patch('netrc.netrc', side_effect=OSError)
1254+
def test_cli_custom_rcfile_error(self, mock_netrc, mock_ftp_cls):
1255+
with mock.patch('sys.argv', ['ftplib', '-rnonexistent.netrc', 'example.com']), \
1256+
support.captured_stderr() as stderr:
1257+
ftplib.test()
1258+
self.assertIn("Could not open account file -- using anonymous login.",
1259+
stderr.getvalue())
1260+
1261+
11911262
def setUpModule():
11921263
thread_info = threading_helper.threading_setup()
11931264
unittest.addModuleCleanup(threading_helper.threading_cleanup, *thread_info)

0 commit comments

Comments
 (0)