~bzr-pqm/bzr/bzr.dev

2221.5.1 by Dmitry Vasiliev
Added support for Putty's SSH implementation
1
# Copyright (C) 2004, 2005, 2006, 2007 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
from bzrlib.tests import TestCase
18
from bzrlib.errors import SSHVendorNotFound, UnknownSSH
19
from bzrlib.transport.ssh import (
20
    OpenSSHSubprocessVendor,
2221.5.16 by Dmitry Vasiliev
Added comments for test_cached_vendor
21
    PLinkSubprocessVendor,
2221.5.1 by Dmitry Vasiliev
Added support for Putty's SSH implementation
22
    SSHCorpSubprocessVendor,
2221.5.16 by Dmitry Vasiliev
Added comments for test_cached_vendor
23
    SSHVendorManager,
2221.5.1 by Dmitry Vasiliev
Added support for Putty's SSH implementation
24
    )
25
26
27
class TestSSHVendorManager(SSHVendorManager):
28
29
    _ssh_version_string = ""
30
31
    def set_ssh_version_string(self, version):
32
        self._ssh_version_string = version
33
34
    def _get_ssh_version_string(self, args):
35
        return self._ssh_version_string
36
37
38
class SSHVendorManagerTests(TestCase):
39
40
    def test_register_vendor(self):
41
        manager = TestSSHVendorManager()
42
        self.assertRaises(SSHVendorNotFound, manager.get_vendor, {})
2221.5.6 by Dmitry Vasiliev
Changed tests to make sure the vendor manager returns the same object as was registered
43
        vendor = object()
44
        manager.register_vendor("vendor", vendor)
45
        self.assertIs(manager.get_vendor({"BZR_SSH": "vendor"}), vendor)
2221.5.1 by Dmitry Vasiliev
Added support for Putty's SSH implementation
46
47
    def test_default_vendor(self):
48
        manager = TestSSHVendorManager()
49
        self.assertRaises(SSHVendorNotFound, manager.get_vendor, {})
2221.5.6 by Dmitry Vasiliev
Changed tests to make sure the vendor manager returns the same object as was registered
50
        vendor = object()
51
        manager.register_default_vendor(vendor)
52
        self.assertIs(manager.get_vendor({}), vendor)
2221.5.1 by Dmitry Vasiliev
Added support for Putty's SSH implementation
53
54
    def test_get_vendor_by_environment(self):
55
        manager = TestSSHVendorManager()
56
        self.assertRaises(SSHVendorNotFound, manager.get_vendor, {})
57
        self.assertRaises(UnknownSSH,
58
            manager.get_vendor, {"BZR_SSH": "vendor"})
2221.5.6 by Dmitry Vasiliev
Changed tests to make sure the vendor manager returns the same object as was registered
59
        vendor = object()
60
        manager.register_vendor("vendor", vendor)
61
        self.assertIs(manager.get_vendor({"BZR_SSH": "vendor"}), vendor)
2221.5.1 by Dmitry Vasiliev
Added support for Putty's SSH implementation
62
63
    def test_get_vendor_by_inspection_openssh(self):
64
        manager = TestSSHVendorManager()
65
        self.assertRaises(SSHVendorNotFound, manager.get_vendor, {})
66
        manager.set_ssh_version_string("OpenSSH")
67
        self.assertIsInstance(manager.get_vendor({}), OpenSSHSubprocessVendor)
68
69
    def test_get_vendor_by_inspection_sshcorp(self):
70
        manager = TestSSHVendorManager()
71
        self.assertRaises(SSHVendorNotFound, manager.get_vendor, {})
72
        manager.set_ssh_version_string("SSH Secure Shell")
73
        self.assertIsInstance(manager.get_vendor({}), SSHCorpSubprocessVendor)
74
75
    def test_get_vendor_by_inspection_plink(self):
76
        manager = TestSSHVendorManager()
77
        self.assertRaises(SSHVendorNotFound, manager.get_vendor, {})
78
        manager.set_ssh_version_string("plink")
3220.1.2 by Dmitry Vasiliev
Re-enabled auto-detection of plink vendor and fixed tests
79
        self.assertIsInstance(manager.get_vendor({}), PLinkSubprocessVendor)
2221.5.1 by Dmitry Vasiliev
Added support for Putty's SSH implementation
80
81
    def test_cached_vendor(self):
82
        manager = TestSSHVendorManager()
83
        self.assertRaises(SSHVendorNotFound, manager.get_vendor, {})
2221.5.6 by Dmitry Vasiliev
Changed tests to make sure the vendor manager returns the same object as was registered
84
        vendor = object()
85
        manager.register_vendor("vendor", vendor)
2221.5.1 by Dmitry Vasiliev
Added support for Putty's SSH implementation
86
        self.assertRaises(SSHVendorNotFound, manager.get_vendor, {})
2221.5.16 by Dmitry Vasiliev
Added comments for test_cached_vendor
87
        # Once the vendor is found the result is cached (mainly because of the
88
        # 'get_vendor' sometimes can be an expensive operation) and later
89
        # invocations of the 'get_vendor' just returns the cached value.
2221.5.6 by Dmitry Vasiliev
Changed tests to make sure the vendor manager returns the same object as was registered
90
        self.assertIs(manager.get_vendor({"BZR_SSH": "vendor"}), vendor)
91
        self.assertIs(manager.get_vendor({}), vendor)
2221.5.16 by Dmitry Vasiliev
Added comments for test_cached_vendor
92
        # The cache can be cleared by the 'clear_cache' method
93
        manager.clear_cache()
94
        self.assertRaises(SSHVendorNotFound, manager.get_vendor, {})
2221.5.1 by Dmitry Vasiliev
Added support for Putty's SSH implementation
95
2221.5.17 by Dmitry Vasiliev
Added comments for test_get_vendor_search_order
96
    def test_get_vendor_search_order(self):
97
        # The 'get_vendor' method search for SSH vendors as following:
98
        #
99
        #   1. Check previously cached value
100
        #   2. Check BZR_SSH environment variable
101
        #   3. Check the system for known SSH vendors
102
        #   4. Fall back to the default vendor if registered
103
        #
104
        # Let's now check the each check method in the reverse order
105
        # clearing the cache between each invocation:
106
2221.5.1 by Dmitry Vasiliev
Added support for Putty's SSH implementation
107
        manager = TestSSHVendorManager()
2221.5.17 by Dmitry Vasiliev
Added comments for test_get_vendor_search_order
108
        # At first no vendors are found
2221.5.1 by Dmitry Vasiliev
Added support for Putty's SSH implementation
109
        self.assertRaises(SSHVendorNotFound, manager.get_vendor, {})
110
2221.5.17 by Dmitry Vasiliev
Added comments for test_get_vendor_search_order
111
        # If the default vendor is registered it will be returned
2221.5.6 by Dmitry Vasiliev
Changed tests to make sure the vendor manager returns the same object as was registered
112
        default_vendor = object()
113
        manager.register_default_vendor(default_vendor)
114
        self.assertIs(manager.get_vendor({}), default_vendor)
2221.5.1 by Dmitry Vasiliev
Added support for Putty's SSH implementation
115
2221.5.17 by Dmitry Vasiliev
Added comments for test_get_vendor_search_order
116
        # If the known vendor is found in the system it will be returned
2221.5.8 by Dmitry Vasiliev
Added SSHVendorManager.clear_cache() method
117
        manager.clear_cache()
2221.5.1 by Dmitry Vasiliev
Added support for Putty's SSH implementation
118
        manager.set_ssh_version_string("OpenSSH")
119
        self.assertIsInstance(manager.get_vendor({}), OpenSSHSubprocessVendor)
120
2221.5.17 by Dmitry Vasiliev
Added comments for test_get_vendor_search_order
121
        # If the BZR_SSH environment variable is found it will be treated as
122
        # the vendor name
2221.5.8 by Dmitry Vasiliev
Added SSHVendorManager.clear_cache() method
123
        manager.clear_cache()
2221.5.6 by Dmitry Vasiliev
Changed tests to make sure the vendor manager returns the same object as was registered
124
        vendor = object()
125
        manager.register_vendor("vendor", vendor)
126
        self.assertIs(manager.get_vendor({"BZR_SSH": "vendor"}), vendor)
2221.5.1 by Dmitry Vasiliev
Added support for Putty's SSH implementation
127
2221.5.17 by Dmitry Vasiliev
Added comments for test_get_vendor_search_order
128
        # Last cached value always checked first
2221.5.6 by Dmitry Vasiliev
Changed tests to make sure the vendor manager returns the same object as was registered
129
        self.assertIs(manager.get_vendor({}), vendor)
2221.5.1 by Dmitry Vasiliev
Added support for Putty's SSH implementation
130
131
132
class SubprocessVendorsTests(TestCase):
133
2221.5.3 by Dmitry Vasiliev
Fixed plink's arguments order. Added tests for such a case.
134
    def test_openssh_command_arguments(self):
135
        vendor = OpenSSHSubprocessVendor()
136
        self.assertEqual(
137
            vendor._get_vendor_specific_argv(
138
                "user", "host", 100, command=["bzr"]),
139
            ["ssh", "-oForwardX11=no", "-oForwardAgent=no",
140
                "-oClearAllForwardings=yes", "-oProtocol=2",
141
                "-oNoHostAuthenticationForLocalhost=yes",
142
                "-p", "100",
143
                "-l", "user",
144
                "host", "bzr"]
145
            )
146
147
    def test_openssh_subsystem_arguments(self):
148
        vendor = OpenSSHSubprocessVendor()
149
        self.assertEqual(
150
            vendor._get_vendor_specific_argv(
151
                "user", "host", 100, subsystem="sftp"),
152
            ["ssh", "-oForwardX11=no", "-oForwardAgent=no",
153
                "-oClearAllForwardings=yes", "-oProtocol=2",
154
                "-oNoHostAuthenticationForLocalhost=yes",
155
                "-p", "100",
156
                "-l", "user",
157
                "-s", "host", "sftp"]
158
            )
159
160
    def test_sshcorp_command_arguments(self):
161
        vendor = SSHCorpSubprocessVendor()
162
        self.assertEqual(
163
            vendor._get_vendor_specific_argv(
164
                "user", "host", 100, command=["bzr"]),
165
            ["ssh", "-x",
166
                "-p", "100",
167
                "-l", "user",
168
                "host", "bzr"]
169
            )
170
171
    def test_sshcorp_subsystem_arguments(self):
172
        vendor = SSHCorpSubprocessVendor()
173
        self.assertEqual(
174
            vendor._get_vendor_specific_argv(
175
                "user", "host", 100, subsystem="sftp"),
176
            ["ssh", "-x",
177
                "-p", "100",
178
                "-l", "user",
179
                "-s", "sftp", "host"]
180
            )
181
182
    def test_plink_command_arguments(self):
183
        vendor = PLinkSubprocessVendor()
184
        self.assertEqual(
185
            vendor._get_vendor_specific_argv(
186
                "user", "host", 100, command=["bzr"]),
3220.1.2 by Dmitry Vasiliev
Re-enabled auto-detection of plink vendor and fixed tests
187
            ["plink", "-x", "-a", "-ssh", "-2", "-batch",
2221.5.3 by Dmitry Vasiliev
Fixed plink's arguments order. Added tests for such a case.
188
                "-P", "100",
189
                "-l", "user",
190
                "host", "bzr"]
191
            )
192
193
    def test_plink_subsystem_arguments(self):
194
        vendor = PLinkSubprocessVendor()
195
        self.assertEqual(
196
            vendor._get_vendor_specific_argv(
197
                "user", "host", 100, subsystem="sftp"),
3220.1.2 by Dmitry Vasiliev
Re-enabled auto-detection of plink vendor and fixed tests
198
            ["plink", "-x", "-a", "-ssh", "-2", "-batch",
2221.5.3 by Dmitry Vasiliev
Fixed plink's arguments order. Added tests for such a case.
199
                "-P", "100",
200
                "-l", "user",
201
                "-s", "host", "sftp"]
2221.5.1 by Dmitry Vasiliev
Added support for Putty's SSH implementation
202
            )