/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1752.2.1 by Martin Pool
Start implementation of a simple ssh server.
1
# Copyright (C) 2006 Canonical Ltd
2
#
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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
"""Tests for ssh transport"""
18
1752.2.4 by Martin Pool
Refactor SFTP transport to allow code sharing with SSH.
19
# TODO: Try sending multiple requests; they should all get answers.
20
21
# TODO: If the server raises an error within its processing that should be
22
# caught and propagated back to the client.
23
1752.2.1 by Martin Pool
Start implementation of a simple ssh server.
24
# all of this deals with byte strings so this is safe
25
from cStringIO import StringIO
26
27
import bzrlib
1752.2.4 by Martin Pool
Refactor SFTP transport to allow code sharing with SSH.
28
from bzrlib import tests, errors, bzrdir
1752.2.3 by Martin Pool
(ssh) more development of error handling
29
from bzrlib.transport import local, memory, ssh
1752.2.1 by Martin Pool
Start implementation of a simple ssh server.
30
31
class TestSSHTransport(tests.TestCase):
32
    
33
    def test_loopback_ssh_connection_exists(self):
34
        ssh.LoopbackSSHConnection()
35
36
    def test_ssh_query_version(self):
37
        """Feed a canned query version to a server"""
38
        to_server = StringIO('hello\0011\n')
39
        from_server = StringIO()
40
        server = ssh.Server(to_server, from_server, local.LocalTransport('file:///'))
41
        server._serve_one_request()
42
        self.assertEqual('bzr server\0011\n',
43
                         from_server.getvalue())
44
1752.2.2 by Martin Pool
SSH get method; more development of framework.
45
    def test_canned_get_response(self):
46
        transport = memory.MemoryTransport('memory:///')
47
        transport.put('hello', StringIO('contents\nof\nfile\n'))
48
        to_server = StringIO('get\001./hello\n')
49
        from_server = StringIO()
50
        server = ssh.Server(to_server, from_server, transport)
51
        server._serve_one_request()
52
        self.assertEqual('ok\n'
53
                         '17\n'
54
                         'contents\nof\nfile\n'
55
                         'done\n',
56
                         from_server.getvalue())
57
1752.2.1 by Martin Pool
Start implementation of a simple ssh server.
58
    def test_open_loopback_server(self):
59
        conn = ssh.LoopbackSSHConnection()
60
        version = conn.query_version()
61
        self.assertEqual(1, version)
62
63
    def test_server_shutdown_on_client_disconnect(self):
64
        conn = ssh.LoopbackSSHConnection()
65
        conn.disconnect()
66
        conn._server_thread.join()
67
        self.assertFalse(conn._server_thread.isAlive())
68
69
    def test_multiple_requests(self):
70
        conn = ssh.LoopbackSSHConnection()
71
        version = conn.query_version()
72
        self.assertEqual(1, version)
73
        version = conn.query_version()
74
        self.assertEqual(1, version)
75
76
    def test_ssh_transport_has(self):
77
        """Checking for file existence over ssh."""
78
        conn = ssh.LoopbackSSHConnection()
79
        conn.backing_transport.put("foo", StringIO("contents of foo\n"))
80
        self.assertTrue(conn.has("foo"))
81
        self.assertFalse(conn.has("non-foo"))
82
1752.2.2 by Martin Pool
SSH get method; more development of framework.
83
    def test_ssh_transport_get(self):
84
        """Read back a file over ssh."""
85
        conn = ssh.LoopbackSSHConnection()
86
        conn.backing_transport.put("foo", StringIO("contents\nof\nfoo\n"))
87
        fp = conn.get("foo")
88
        self.assertEqual('contents\nof\nfoo\n', fp.read())
89
        
1752.2.3 by Martin Pool
(ssh) more development of error handling
90
    def test_get_error_enoent(self):
1752.2.2 by Martin Pool
SSH get method; more development of framework.
91
        """Error reported from server getting nonexistent file."""
92
        conn = ssh.LoopbackSSHConnection()
1752.2.3 by Martin Pool
(ssh) more development of error handling
93
        try:
94
            conn.get('not a file')
95
        except errors.NoSuchFile, e:
96
            self.assertEqual('not a file', e.path)
97
        else:
98
            self.fail("get did not raise expected error")
99
100
    def test_get_error_unexpected(self):
101
        """Error reported by server with no specific representation"""
102
        class FlakyTransport(object):
103
            def get(self, path):
104
                raise Exception("some random exception from inside server")
1752.2.4 by Martin Pool
Refactor SFTP transport to allow code sharing with SSH.
105
        conn = ssh.LoopbackSSHConnection(backing_transport=FlakyTransport())
1752.2.3 by Martin Pool
(ssh) more development of error handling
106
        try:
107
            conn.get('something')
108
        except errors.TransportError, e:
109
            self.assertContainsRe(str(e), 'some random exception')
110
        else:
111
            self.fail("get did not raise expected error")
112
1752.2.4 by Martin Pool
Refactor SFTP transport to allow code sharing with SSH.
113
    def test_loopback_conn_has_base_url(self):
114
        conn = ssh.LoopbackSSHConnection()
115
        self.assertEquals('ssh+loopback:///', conn.base)
116
117
    def test_simple_clone_conn(self):
118
        """Test that cloning reuses the same connection."""
119
        conn = ssh.LoopbackSSHConnection()
120
        # we create a real connection not a loopback one, but it will use the
121
        # same server and pipes
122
        conn2 = ssh.SSHConnection('ssh+loopback:///', clone_from=conn)
123
        conn2.query_version()
124
125
    def test_abspath(self):
126
        conn = ssh.LoopbackSSHConnection()
127
        self.assertEquals('ssh+loopback:///foo/bar',
128
                          conn.abspath('foo/bar'))
129
130
    def test_open_dir(self):
131
        """Test changing directory"""
132
        return ################################################
133
        conn = ssh.LoopbackSSHConnection()
134
        conn.backing_transport.mkdir('toffee')
135
        conn.backing_transport.mkdir('toffee/apple')
136
        self.assertTrue(conn.has('toffee'))
137
138
        sub_conn = conn.clone('toffee')
139
        self.assertTrue(sub_conn.has('apple'))
140
141
    def test_open_bzrdir(self):
142
        """Open an existing bzrdir over ssh transport"""
143
        return ################################################
144
        conn = ssh.LoopbackSSHConnection()
145
        t = conn.backing_transport
146
        bzrdir.BzrDirFormat.get_default_format().initialize_on_transport(t)
147
        result_dir = bzrdir.BzrDir.open_containing_from_transport(conn)