~bzr-pqm/bzr/bzr.dev

5557.1.15 by John Arbash Meinel
Merge bzr.dev 5597 to resolve NEWS, aka bzr-2.3.txt
1
# Copyright (C) 2006, 2007, 2009, 2010, 2011 Canonical Ltd
2052.3.1 by John Arbash Meinel
Add tests to cleanup the copyright of all source files
2
#
1952.1.1 by John Arbash Meinel
Ghozzy: Fix Bzr's support of Active FTP (aftp://)
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1952.1.1 by John Arbash Meinel
Ghozzy: Fix Bzr's support of Active FTP (aftp://)
16
5060.3.1 by Martin Pool
Handle "Directory not empty" from ftp as DirectoryNotEmpty.
17
import ftplib
4222.3.14 by Jelmer Vernooij
Fix missing import.
18
import getpass
2790.1.1 by Vincent Ladeuil
Fix #137044 by prompting for a password if *none* is provided for ftp.
19
2790.1.2 by Vincent Ladeuil
Review feedback.
20
from bzrlib import (
2900.2.5 by Vincent Ladeuil
ake ftp aware of authentication config.
21
    config,
5060.3.1 by Martin Pool
Handle "Directory not empty" from ftp as DirectoryNotEmpty.
22
    errors,
2790.1.2 by Vincent Ladeuil
Review feedback.
23
    tests,
24
    transport,
25
    ui,
6379.4.2 by Jelmer Vernooij
Add urlutils.quote / urlutils.unquote.
26
    urlutils,
2790.1.2 by Vincent Ladeuil
Review feedback.
27
    )
28
5060.3.1 by Martin Pool
Handle "Directory not empty" from ftp as DirectoryNotEmpty.
29
from bzrlib.transport import ftp
30
3508.1.7 by Vincent Ladeuil
Prepare test framework for pyftpdlib injection.
31
from bzrlib.tests import ftp_server
32
2790.1.2 by Vincent Ladeuil
Review feedback.
33
34
class TestCaseWithFTPServer(tests.TestCaseWithTransport):
2413.1.1 by John Arbash Meinel
Implement TestCaseWithFTPServer using the new shiny Feature mechanism.
35
3508.1.7 by Vincent Ladeuil
Prepare test framework for pyftpdlib injection.
36
    _test_needs_features = [ftp_server.FTPServerFeature]
2413.1.1 by John Arbash Meinel
Implement TestCaseWithFTPServer using the new shiny Feature mechanism.
37
38
    def setUp(self):
3508.1.23 by Vincent Ladeuil
Fix as per Martin's review.
39
        self.transport_server = ftp_server.FTPTestServer
2413.1.1 by John Arbash Meinel
Implement TestCaseWithFTPServer using the new shiny Feature mechanism.
40
        super(TestCaseWithFTPServer, self).setUp()
41
42
2790.1.2 by Vincent Ladeuil
Review feedback.
43
class TestCaseAFTP(tests.TestCaseWithTransport):
2413.1.2 by John Arbash Meinel
Clean up test ordering
44
    """Test aftp transport."""
45
46
    def test_aftp_degrade(self):
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
47
        t = transport.get_transport_from_url('aftp://host/path')
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
48
        self.assertTrue(t.is_active)
2413.1.2 by John Arbash Meinel
Clean up test ordering
49
        parent = t.clone('..')
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
50
        self.assertTrue(parent.is_active)
2413.1.2 by John Arbash Meinel
Clean up test ordering
51
52
        self.assertEqual('aftp://host/path', t.abspath(''))
53
54
3508.1.23 by Vincent Ladeuil
Fix as per Martin's review.
55
class TestFTPTestServer(TestCaseWithFTPServer):
2413.1.1 by John Arbash Meinel
Implement TestCaseWithFTPServer using the new shiny Feature mechanism.
56
57
    def test_basic_exists(self):
58
        url = self.get_url()
59
        self.assertStartsWith(url, 'ftp://')
60
61
        t = self.get_transport()
62
        t.put_bytes('foo', 'test bytes\n')
63
        self.assertEqual('test bytes\n', t.get_bytes('foo'))
2790.1.1 by Vincent Ladeuil
Fix #137044 by prompting for a password if *none* is provided for ftp.
64
2917.1.1 by Vincent Ladeuil
Reproduce the bug.
65
    def test__reconnect(self):
66
        t = self.get_transport()
67
        t.put_bytes('foo', 'test bytes\n')
68
        self.assertEqual('test bytes\n', t.get_bytes('foo'))
69
        t._reconnect()
2917.1.3 by Vincent Ladeuil
Review feedback.
70
        t.put_bytes('foo', 'test more bytes\n')
71
        self.assertEqual('test more bytes\n', t.get_bytes('foo'))
2917.1.1 by Vincent Ladeuil
Reproduce the bug.
72
2790.1.1 by Vincent Ladeuil
Fix #137044 by prompting for a password if *none* is provided for ftp.
73
3508.1.23 by Vincent Ladeuil
Fix as per Martin's review.
74
class TestFTPTestServerUI(TestCaseWithFTPServer):
2790.1.1 by Vincent Ladeuil
Fix #137044 by prompting for a password if *none* is provided for ftp.
75
3508.1.13 by Vincent Ladeuil
Fix last failing tests under python2.6.
76
    def setUp(self):
3508.1.23 by Vincent Ladeuil
Fix as per Martin's review.
77
        super(TestFTPTestServerUI, self).setUp()
3508.1.13 by Vincent Ladeuil
Fix last failing tests under python2.6.
78
        self.user = 'joe'
79
        self.password = 'secret'
80
        self.get_server().add_user(self.user, self.password)
81
82
    def get_url(self, relpath=None):
83
        """Overrides get_url to inject our user."""
3508.1.23 by Vincent Ladeuil
Fix as per Martin's review.
84
        base = super(TestFTPTestServerUI, self).get_url(relpath)
6055.2.1 by Jelmer Vernooij
Add UnparsedUrl.
85
        parsed_url = transport.ConnectedTransport._split_url(base)
5268.7.16 by Jelmer Vernooij
Use URL.
86
        new_url = parsed_url.clone()
87
        new_url.user = self.user
6379.4.2 by Jelmer Vernooij
Add urlutils.quote / urlutils.unquote.
88
        new_url.quoted_user = urlutils.quote(self.user)
5268.7.16 by Jelmer Vernooij
Use URL.
89
        new_url.password = self.password
6379.4.2 by Jelmer Vernooij
Add urlutils.quote / urlutils.unquote.
90
        new_url.quoted_password = urlutils.quote(self.password)
5268.7.16 by Jelmer Vernooij
Use URL.
91
        return str(new_url)
2900.2.15 by Vincent Ladeuil
AuthenticationConfig can be queried for logins too (first step).
92
4222.3.13 by Jelmer Vernooij
Add tests to ensure sftp and ftp don't prompt for usernames.
93
    def test_no_prompt_for_username(self):
94
        """ensure getpass.getuser() is used if there's no username in the 
95
        configuration.""",
96
        self.get_server().add_user(getpass.getuser(), self.password)
97
        t = self.get_transport()
4449.3.46 by Martin Pool
Update ftp tests to use CannedInputUIFactory
98
        ui.ui_factory = ui.CannedInputUIFactory([self.password])
4222.3.13 by Jelmer Vernooij
Add tests to ensure sftp and ftp don't prompt for usernames.
99
        # Issue a request to the server to connect
100
        t.put_bytes('foo', 'test bytes\n')
101
        self.assertEqual('test bytes\n', t.get_bytes('foo'))
102
        # Only the password should've been read
4449.3.46 by Martin Pool
Update ftp tests to use CannedInputUIFactory
103
        ui.ui_factory.assert_all_input_consumed()
4222.3.13 by Jelmer Vernooij
Add tests to ensure sftp and ftp don't prompt for usernames.
104
2790.1.1 by Vincent Ladeuil
Fix #137044 by prompting for a password if *none* is provided for ftp.
105
    def test_prompt_for_password(self):
106
        t = self.get_transport()
4449.3.46 by Martin Pool
Update ftp tests to use CannedInputUIFactory
107
        ui.ui_factory = ui.CannedInputUIFactory([self.password])
2790.1.1 by Vincent Ladeuil
Fix #137044 by prompting for a password if *none* is provided for ftp.
108
        # Issue a request to the server to connect
109
        t.has('whatever/not/existing')
110
        # stdin should be empty (the provided password have been consumed)
4449.3.46 by Martin Pool
Update ftp tests to use CannedInputUIFactory
111
        ui.ui_factory.assert_all_input_consumed()
2900.2.5 by Vincent Ladeuil
ake ftp aware of authentication config.
112
113
    def test_no_prompt_for_password_when_using_auth_config(self):
114
        t = self.get_transport()
4449.3.46 by Martin Pool
Update ftp tests to use CannedInputUIFactory
115
        ui.ui_factory = ui.CannedInputUIFactory([])
2900.2.5 by Vincent Ladeuil
ake ftp aware of authentication config.
116
        # Create a config file with the right password
117
        conf = config.AuthenticationConfig()
2900.2.14 by Vincent Ladeuil
More tests.
118
        conf._get_config().update({'ftptest': {'scheme': 'ftp',
3508.1.13 by Vincent Ladeuil
Fix last failing tests under python2.6.
119
                                               'user': self.user,
120
                                               'password': self.password}})
2900.2.5 by Vincent Ladeuil
ake ftp aware of authentication config.
121
        conf._save()
122
        # Issue a request to the server to connect
123
        t.put_bytes('foo', 'test bytes\n')
124
        self.assertEqual('test bytes\n', t.get_bytes('foo'))
3508.1.17 by Vincent Ladeuil
Allows empty passwords with pyftpdlib ftp test server.
125
126
    def test_empty_password(self):
127
        # Override the default user/password from setUp
128
        self.user = 'jim'
129
        self.password = ''
130
        self.get_server().add_user(self.user, self.password)
131
        t = self.get_transport()
4449.3.47 by Martin Pool
Typo correction
132
        ui.ui_factory = ui.CannedInputUIFactory([self.password])
3508.1.17 by Vincent Ladeuil
Allows empty passwords with pyftpdlib ftp test server.
133
        # Issue a request to the server to connect
134
        t.has('whatever/not/existing')
135
        # stdin should be empty (the provided password have been consumed),
136
        # even if the password is empty, it's followed by a newline.
4449.3.46 by Martin Pool
Update ftp tests to use CannedInputUIFactory
137
        ui.ui_factory.assert_all_input_consumed()
5060.3.1 by Martin Pool
Handle "Directory not empty" from ftp as DirectoryNotEmpty.
138
139
140
class TestFTPErrorTranslation(tests.TestCase):
141
142
    def test_translate_directory_not_empty(self):
143
        # https://bugs.launchpad.net/bugs/528722
144
        
145
        t = ftp.FtpTransport("ftp://none/")
146
147
        try:
148
            raise ftplib.error_temp("Rename/move failure: Directory not empty")
149
        except Exception, e:
150
            e = self.assertRaises(errors.DirectoryNotEmpty,
151
                t._translate_ftp_error, e, "/path")