/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2052.3.2 by John Arbash Meinel
Change Copyright .. by Canonical to Copyright ... Canonical
1
# Copyright (C) 2006 Canonical Ltd
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
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
18
"""Tests of the bzr serve command."""
19
2018.1.2 by Andrew Bennetts
Tidy imports, skip test if paramiko isn't installed.
20
import os
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
21
import signal
2018.1.2 by Andrew Bennetts
Tidy imports, skip test if paramiko isn't installed.
22
import subprocess
2309.2.5 by Alexander Belchenko
test_bzr_connect_to_bzr_ssh: win32-compatibility
23
import sys
2018.1.2 by Andrew Bennetts
Tidy imports, skip test if paramiko isn't installed.
24
import threading
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
25
2309.2.5 by Alexander Belchenko
test_bzr_connect_to_bzr_ssh: win32-compatibility
26
from bzrlib import (
27
    errors,
28
    osutils,
2598.5.1 by Aaron Bentley
Start eliminating the use of None to indicate null revision
29
    revision as _mod_revision,
2309.2.5 by Alexander Belchenko
test_bzr_connect_to_bzr_ssh: win32-compatibility
30
    )
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
31
from bzrlib.branch import Branch
1910.19.11 by Andrew Bennetts
General code cleanup based on review comments and other observations.
32
from bzrlib.bzrdir import BzrDir
2018.1.2 by Andrew Bennetts
Tidy imports, skip test if paramiko isn't installed.
33
from bzrlib.errors import ParamikoNotPresent
2400.1.9 by Andrew Bennetts
Fix blackbox/test_serve, there were some trivial changes that needed to be brought across from the hpss branch.
34
from bzrlib.smart import medium
2018.1.2 by Andrew Bennetts
Tidy imports, skip test if paramiko isn't installed.
35
from bzrlib.tests import TestCaseWithTransport, TestSkipped
2018.5.21 by Andrew Bennetts
Move bzrlib.transport.smart to bzrlib.smart
36
from bzrlib.transport import get_transport, remote
1910.19.11 by Andrew Bennetts
General code cleanup based on review comments and other observations.
37
38
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
39
class TestBzrServe(TestCaseWithTransport):
1910.19.11 by Andrew Bennetts
General code cleanup based on review comments and other observations.
40
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
41
    def assertInetServerShutsdownCleanly(self, process):
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
42
        """Shutdown the server process looking for errors."""
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
43
        # Shutdown the server: the server should shut down when it cannot read
44
        # from stdin anymore.
45
        process.stdin.close()
1910.19.11 by Andrew Bennetts
General code cleanup based on review comments and other observations.
46
        # Hide stdin from the subprocess module, so it won't fail to close it.
47
        process.stdin = None
2581.1.2 by Martin Pool
Remove unnecessary retcode=0 to run_bzr calls
48
        result = self.finish_bzr_subprocess(process)
1910.19.11 by Andrew Bennetts
General code cleanup based on review comments and other observations.
49
        self.assertEqual('', result[0])
50
        self.assertEqual('', result[1])
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
51
    
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
52
    def assertServerFinishesCleanly(self, process):
53
        """Shutdown the bzr serve instance process looking for errors."""
54
        # Shutdown the server
55
        result = self.finish_bzr_subprocess(process, retcode=3,
56
                                            send_signal=signal.SIGINT)
57
        self.assertEqual('', result[0])
58
        self.assertEqual('bzr: interrupted\n', result[1])
59
60
    def start_server_inet(self, extra_options=()):
61
        """Start a bzr server subprocess using the --inet option.
62
63
        :param extra_options: extra options to give the server.
64
        :return: a tuple with the bzr process handle for passing to
65
            finish_bzr_subprocess, a client for the server, and a transport.
66
        """
67
        # Serve from the current directory
68
        process = self.start_bzr_subprocess(['serve', '--inet'])
69
70
        # Connect to the server
71
        # We use this url because while this is no valid URL to connect to this
72
        # server instance, the transport needs a URL.
2018.5.15 by Andrew Bennetts
Tidy some imports, and bugs introduced when adding server.py
73
        client_medium = medium.SmartSimplePipesClientMedium(
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
74
            process.stdout, process.stdin)
2018.5.21 by Andrew Bennetts
Move bzrlib.transport.smart to bzrlib.smart
75
        transport = remote.RemoteTransport(
2018.5.15 by Andrew Bennetts
Tidy some imports, and bugs introduced when adding server.py
76
            'bzr://localhost/', medium=client_medium)
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
77
        return process, transport
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
78
79
    def start_server_port(self, extra_options=()):
80
        """Start a bzr server subprocess.
81
82
        :param extra_options: extra options to give the server.
83
        :return: a tuple with the bzr process handle for passing to
84
            finish_bzr_subprocess, and the base url for the server.
85
        """
86
        # Serve from the current directory
87
        args = ['serve', '--port', 'localhost:0']
88
        args.extend(extra_options)
89
        process = self.start_bzr_subprocess(args, skip_if_plan_to_signal=True)
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
90
        port_line = process.stdout.readline()
91
        prefix = 'listening on port: '
92
        self.assertStartsWith(port_line, prefix)
93
        port = int(port_line[len(prefix):])
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
94
        return process,'bzr://localhost:%d/' % port
95
96
    def test_bzr_serve_inet_readonly(self):
97
        """bzr server should provide a read only filesystem by default."""
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
98
        process, transport = self.start_server_inet()
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
99
        self.assertRaises(errors.TransportNotPossible, transport.mkdir, 'adir')
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
100
        self.assertInetServerShutsdownCleanly(process)
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
101
102
    def test_bzr_serve_inet_readwrite(self):
103
        # Make a branch
104
        self.make_branch('.')
105
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
106
        process, transport = self.start_server_inet(['--allow-writes'])
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
107
108
        # We get a working branch
109
        branch = BzrDir.open_from_transport(transport).open_branch()
110
        branch.repository.get_revision_graph()
2598.5.4 by Aaron Bentley
Restore original Branch.last_revision behavior, fix bits that care
111
        self.assertEqual(_mod_revision.NULL_REVISION,
112
                         _mod_revision.ensure_null(branch.last_revision()))
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
113
        self.assertInetServerShutsdownCleanly(process)
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
114
115
    def test_bzr_serve_port_readonly(self):
116
        """bzr server should provide a read only filesystem by default."""
117
        process, url = self.start_server_port()
118
        transport = get_transport(url)
119
        self.assertRaises(errors.TransportNotPossible, transport.mkdir, 'adir')
120
        self.assertServerFinishesCleanly(process)
121
122
    def test_bzr_serve_port_readwrite(self):
123
        # Make a branch
124
        self.make_branch('.')
125
126
        process, url = self.start_server_port(['--allow-writes'])
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
127
128
        # Connect to the server
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
129
        branch = Branch.open(url)
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
130
131
        # We get a working branch
132
        branch.repository.get_revision_graph()
2598.5.4 by Aaron Bentley
Restore original Branch.last_revision behavior, fix bits that care
133
        self.assertEqual(_mod_revision.NULL_REVISION,
134
                         _mod_revision.ensure_null(branch.last_revision()))
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
135
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
136
        self.assertServerFinishesCleanly(process)
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
137
2018.1.1 by Andrew Bennetts
Make bzr+ssh:// actually work (at least with absolute paths).
138
    def test_bzr_connect_to_bzr_ssh(self):
2018.1.7 by Andrew Bennetts
Use bzrlib rather than a bzr subprocess in test_bzr_connect_to_bzr_ssh.
139
        """User acceptance that get_transport of a bzr+ssh:// behaves correctly.
140
141
        bzr+ssh:// should cause bzr to run a remote bzr smart server over SSH.
142
        """
2018.1.2 by Andrew Bennetts
Tidy imports, skip test if paramiko isn't installed.
143
        try:
144
            from bzrlib.transport.sftp import SFTPServer
145
        except ParamikoNotPresent:
146
            raise TestSkipped('Paramiko not installed')
147
        from bzrlib.tests.stub_sftp import StubServer
2018.1.11 by Andrew Bennetts
Improvements to test_bzr_connect_to_bzr_ssh based on review comments
148
        
2018.1.1 by Andrew Bennetts
Make bzr+ssh:// actually work (at least with absolute paths).
149
        # Make a branch
2018.1.2 by Andrew Bennetts
Tidy imports, skip test if paramiko isn't installed.
150
        self.make_branch('a_branch')
2018.1.1 by Andrew Bennetts
Make bzr+ssh:// actually work (at least with absolute paths).
151
152
        # Start an SSH server
2018.1.11 by Andrew Bennetts
Improvements to test_bzr_connect_to_bzr_ssh based on review comments
153
        self.command_executed = []
2018.1.1 by Andrew Bennetts
Make bzr+ssh:// actually work (at least with absolute paths).
154
        # XXX: This is horrible -- we define a really dumb SSH server that
155
        # executes commands, and manage the hooking up of stdin/out/err to the
156
        # SSH channel ourselves.  Surely this has already been implemented
157
        # elsewhere?
2018.1.2 by Andrew Bennetts
Tidy imports, skip test if paramiko isn't installed.
158
        class StubSSHServer(StubServer):
159
2018.1.1 by Andrew Bennetts
Make bzr+ssh:// actually work (at least with absolute paths).
160
            test = self
161
162
            def check_channel_exec_request(self, channel, command):
2018.1.11 by Andrew Bennetts
Improvements to test_bzr_connect_to_bzr_ssh based on review comments
163
                self.test.command_executed.append(command)
2018.1.1 by Andrew Bennetts
Make bzr+ssh:// actually work (at least with absolute paths).
164
                proc = subprocess.Popen(
165
                    command, shell=True, stdin=subprocess.PIPE,
166
                    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
167
                
168
                # XXX: horribly inefficient, not to mention ugly.
2018.1.11 by Andrew Bennetts
Improvements to test_bzr_connect_to_bzr_ssh based on review comments
169
                # Start a thread for each of stdin/out/err, and relay bytes from
170
                # the subprocess to channel and vice versa.
171
                def ferry_bytes(read, write, close):
2018.1.1 by Andrew Bennetts
Make bzr+ssh:// actually work (at least with absolute paths).
172
                    while True:
2018.1.11 by Andrew Bennetts
Improvements to test_bzr_connect_to_bzr_ssh based on review comments
173
                        bytes = read(1)
2018.1.1 by Andrew Bennetts
Make bzr+ssh:// actually work (at least with absolute paths).
174
                        if bytes == '':
2018.1.11 by Andrew Bennetts
Improvements to test_bzr_connect_to_bzr_ssh based on review comments
175
                            close()
2018.1.1 by Andrew Bennetts
Make bzr+ssh:// actually work (at least with absolute paths).
176
                            break
2018.1.11 by Andrew Bennetts
Improvements to test_bzr_connect_to_bzr_ssh based on review comments
177
                        write(bytes)
2018.1.1 by Andrew Bennetts
Make bzr+ssh:// actually work (at least with absolute paths).
178
2018.1.11 by Andrew Bennetts
Improvements to test_bzr_connect_to_bzr_ssh based on review comments
179
                file_functions = [
180
                    (channel.recv, proc.stdin.write, proc.stdin.close),
181
                    (proc.stdout.read, channel.sendall, channel.close),
182
                    (proc.stderr.read, channel.sendall_stderr, channel.close)]
183
                for read, write, close in file_functions:
184
                    t = threading.Thread(
185
                        target=ferry_bytes, args=(read, write, close))
186
                    t.start()
2018.1.1 by Andrew Bennetts
Make bzr+ssh:// actually work (at least with absolute paths).
187
188
                return True
189
2018.1.2 by Andrew Bennetts
Tidy imports, skip test if paramiko isn't installed.
190
        ssh_server = SFTPServer(StubSSHServer)
2018.1.7 by Andrew Bennetts
Use bzrlib rather than a bzr subprocess in test_bzr_connect_to_bzr_ssh.
191
        # XXX: We *don't* want to override the default SSH vendor, so we set
192
        # _vendor to what _get_ssh_vendor returns.
2018.1.1 by Andrew Bennetts
Make bzr+ssh:// actually work (at least with absolute paths).
193
        ssh_server.setUp()
194
        self.addCleanup(ssh_server.tearDown)
195
        port = ssh_server._listener.port
196
197
        # Access the branch via a bzr+ssh URL.  The BZR_REMOTE_PATH environment
198
        # variable is used to tell bzr what command to run on the remote end.
2309.2.5 by Alexander Belchenko
test_bzr_connect_to_bzr_ssh: win32-compatibility
199
        path_to_branch = osutils.abspath('a_branch')
2018.1.1 by Andrew Bennetts
Make bzr+ssh:// actually work (at least with absolute paths).
200
        
2018.1.7 by Andrew Bennetts
Use bzrlib rather than a bzr subprocess in test_bzr_connect_to_bzr_ssh.
201
        orig_bzr_remote_path = os.environ.get('BZR_REMOTE_PATH')
2309.2.5 by Alexander Belchenko
test_bzr_connect_to_bzr_ssh: win32-compatibility
202
        bzr_remote_path = self.get_bzr_path()
203
        if sys.platform == 'win32':
204
            bzr_remote_path = sys.executable + ' ' + self.get_bzr_path()
205
        os.environ['BZR_REMOTE_PATH'] = bzr_remote_path
2018.1.7 by Andrew Bennetts
Use bzrlib rather than a bzr subprocess in test_bzr_connect_to_bzr_ssh.
206
        try:
2309.2.5 by Alexander Belchenko
test_bzr_connect_to_bzr_ssh: win32-compatibility
207
            if sys.platform == 'win32':
208
                path_to_branch = os.path.splitdrive(path_to_branch)[1]
2018.1.7 by Andrew Bennetts
Use bzrlib rather than a bzr subprocess in test_bzr_connect_to_bzr_ssh.
209
            branch = Branch.open(
2018.1.9 by Andrew Bennetts
Implement ParamikoVendor.connect_ssh
210
                'bzr+ssh://fred:secret@localhost:%d%s' % (port, path_to_branch))
2018.1.7 by Andrew Bennetts
Use bzrlib rather than a bzr subprocess in test_bzr_connect_to_bzr_ssh.
211
            
212
            branch.repository.get_revision_graph()
2598.5.1 by Aaron Bentley
Start eliminating the use of None to indicate null revision
213
            self.assertEqual(_mod_revision.NULL_REVISION,
2598.5.4 by Aaron Bentley
Restore original Branch.last_revision behavior, fix bits that care
214
                             _mod_revision.ensure_null(branch.last_revision()))
2018.1.10 by Andrew Bennetts
Merge --allow-writes from Robert
215
            # Check we can perform write operations
216
            branch.bzrdir.root_transport.mkdir('foo')
2018.1.7 by Andrew Bennetts
Use bzrlib rather than a bzr subprocess in test_bzr_connect_to_bzr_ssh.
217
        finally:
218
            # Restore the BZR_REMOTE_PATH environment variable back to its
219
            # original state.
220
            if orig_bzr_remote_path is None:
221
                del os.environ['BZR_REMOTE_PATH']
222
            else:
223
                os.environ['BZR_REMOTE_PATH'] = orig_bzr_remote_path
224
2018.1.1 by Andrew Bennetts
Make bzr+ssh:// actually work (at least with absolute paths).
225
        self.assertEqual(
2018.1.11 by Andrew Bennetts
Improvements to test_bzr_connect_to_bzr_ssh based on review comments
226
            ['%s serve --inet --directory=/ --allow-writes'
2309.2.5 by Alexander Belchenko
test_bzr_connect_to_bzr_ssh: win32-compatibility
227
             % bzr_remote_path],
2018.1.1 by Andrew Bennetts
Make bzr+ssh:// actually work (at least with absolute paths).
228
            self.command_executed)
229