source: test/test_error.py @ 1483:0079a3a8be44

Last change on this file since 1483:0079a3a8be44 was 1483:0079a3a8be44, checked in by Stefan Schwarzer <sschwarzer@…>, 7 years ago
Avoid `UnicodeDecodeError` for non-ASCII server messages. See ticket #77. The test simulates the server error by raising an `ftplib.error_perm` directly.
File size: 3.1 KB
Line 
1# encoding: utf-8
2# Copyright (C) 2002-2014, Stefan Schwarzer <sschwarzer@sschwarzer.net>
3# See the file LICENSE for licensing terms.
4
5from __future__ import unicode_literals
6
7import ftplib
8import unittest
9
10import ftputil.error
11
12
13class TestFTPErrorArguments(unittest.TestCase):
14    """
15    The `*Error` constructors should accept either a byte string or a
16    unicode string.
17    """
18
19    def test_bytestring_argument(self):
20        # An umlaut as latin-1 character
21        io_error = ftputil.error.FTPIOError(b"\xe4")
22        os_error = ftputil.error.FTPOSError(b"\xe4")
23
24    def test_unicode_argument(self):
25        # An umlaut as unicode character
26        io_error = ftputil.error.FTPIOError("\xe4")
27        os_error = ftputil.error.FTPOSError("\xe4")
28
29
30class TestErrorConversion(unittest.TestCase):
31
32    def callee(self):
33        raise ftplib.error_perm()
34
35    def test_ftplib_error_to_ftp_os_error(self):
36        """
37        Ensure the `ftplib` exception isn't used as `FTPOSError`
38        argument.
39        """
40        try:
41            with ftputil.error.ftplib_error_to_ftp_os_error:
42                self.callee()
43        except ftputil.error.FTPOSError as exc:
44            self.assertFalse(exc.args and
45                             isinstance(exc.args[0], ftplib.error_perm))
46        else:
47            # We shouldn't come here.
48            self.fail()
49
50    def test_ftplib_error_to_ftp_os_error_non_ascii_server_message(self):
51        """
52        Test that we don't get a `UnicodeDecodeError` if the server
53        sends a message containing non-ASCII characters.
54        """
55        # See ticket #77.
56        message = \
57          ftputil.tool.as_bytes("Não é possível criar um arquivo já existente.")
58        try:
59            with ftputil.error.ftplib_error_to_ftp_os_error:
60                raise ftplib.error_perm(message)
61        # We expect a `PermanentError`.
62        except ftputil.error.PermanentError:
63            pass
64        except UnicodeDecodeError:
65            self.fail()
66
67    def test_ftplib_error_to_ftp_io_error(self):
68        """
69        Ensure the `ftplib` exception isn't used as `FTPIOError`
70        argument.
71        """
72        try:
73            with ftputil.error.ftplib_error_to_ftp_io_error:
74                self.callee()
75        except ftputil.error.FTPIOError as exc:
76            self.assertFalse(exc.args and
77                             isinstance(exc.args[0], ftplib.error_perm))
78        else:
79            # We shouldn't come here.
80            self.fail()
81
82    def test_error_message_reuse(self):
83        """
84        Test if the error message string is retained if the caugt
85        exception has more than one element in `args`.
86        """
87        # See ticket #76.
88        try:
89            # Format "host:port" doesn't work.
90            host = ftputil.FTPHost("localhost:21", "", "")
91        except ftputil.error.FTPOSError as exc:
92            # The error message might change for future Python
93            # versions, so possibly relax the assertion later.
94            self.assertTrue("[Errno -2] Name or service not known" in
95                            str(exc))
96
97
98if __name__ == "__main__":
99    unittest.main()
Note: See TracBrowser for help on using the repository browser.