13
13
# You should have received a copy of the GNU General Public License
14
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
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
18
"""Tests of the bzr serve command."""
26
27
from bzrlib import (
29
30
revision as _mod_revision,
31
33
from bzrlib.branch import Branch
32
34
from bzrlib.bzrdir import BzrDir
33
35
from bzrlib.errors import ParamikoNotPresent
34
from bzrlib.smart import medium
36
from bzrlib.smart import client, medium
37
from bzrlib.smart.server import SmartTCPServer
35
38
from bzrlib.tests import TestCaseWithTransport, TestSkipped
39
from bzrlib.trace import mutter
36
40
from bzrlib.transport import get_transport, remote
97
101
args = ['serve', '--port', 'localhost:0']
98
102
args.extend(extra_options)
99
103
process = self.start_bzr_subprocess(args, skip_if_plan_to_signal=True)
100
port_line = process.stdout.readline()
104
port_line = process.stderr.readline()
101
105
prefix = 'listening on port: '
102
106
self.assertStartsWith(port_line, prefix)
103
107
port = int(port_line[len(prefix):])
138
142
self.make_read_requests(branch)
139
143
self.assertServerFinishesCleanly(process)
145
def test_bzr_serve_supports_protocol(self):
147
self.make_branch('.')
149
process, url = self.start_server_port(['--allow-writes',
152
# Connect to the server
153
branch = Branch.open(url)
154
self.make_read_requests(branch)
155
self.assertServerFinishesCleanly(process)
141
157
def test_bzr_connect_to_bzr_ssh(self):
142
158
"""User acceptance that get_transport of a bzr+ssh:// behaves correctly.
167
183
proc = subprocess.Popen(
168
184
command, shell=True, stdin=subprocess.PIPE,
169
185
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
171
187
# XXX: horribly inefficient, not to mention ugly.
172
188
# Start a thread for each of stdin/out/err, and relay bytes from
173
189
# the subprocess to channel and vice versa.
193
209
ssh_server = SFTPServer(StubSSHServer)
194
210
# XXX: We *don't* want to override the default SSH vendor, so we set
195
211
# _vendor to what _get_ssh_vendor returns.
197
self.addCleanup(ssh_server.tearDown)
212
self.start_server(ssh_server)
198
213
port = ssh_server._listener.port
200
215
# Access the branch via a bzr+ssh URL. The BZR_REMOTE_PATH environment
201
216
# variable is used to tell bzr what command to run on the remote end.
202
217
path_to_branch = osutils.abspath('a_branch')
204
219
orig_bzr_remote_path = os.environ.get('BZR_REMOTE_PATH')
205
220
bzr_remote_path = self.get_bzr_path()
206
221
if sys.platform == 'win32':
226
241
['%s serve --inet --directory=/ --allow-writes'
227
242
% bzr_remote_path],
228
243
self.command_executed)
246
class TestCmdServeChrooting(TestCaseWithTransport):
248
def test_serve_tcp(self):
249
"""'bzr serve' wraps the given --directory in a ChrootServer.
251
So requests that search up through the parent directories (like
252
find_repositoryV3) will give "not found" responses, rather than
253
InvalidURLJoin or jail break errors.
255
t = self.get_transport()
256
t.mkdir('server-root')
257
self.run_bzr_serve_then_func(
258
['--port', '0', '--directory', t.local_abspath('server-root'),
260
self.when_server_started)
261
# The when_server_started method issued a find_repositoryV3 that should
262
# fail with 'norepository' because there are no repositories inside the
264
self.assertEqual(('norepository',), self.client_resp)
266
def run_bzr_serve_then_func(self, serve_args, func, *func_args,
268
"""Run 'bzr serve', and run the given func in a thread once the server
271
When 'func' terminates, the server will be terminated too.
274
def on_server_start(backing_urls, tcp_server):
275
t = threading.Thread(
276
target=on_server_start_thread, args=(tcp_server,))
278
def on_server_start_thread(tcp_server):
281
self.tcp_server = tcp_server
283
func(*func_args, **func_kwargs)
285
# Log errors to make some test failures a little less
287
mutter('func broke: %r', e)
289
# Then stop the server
290
mutter('interrupting...')
291
thread.interrupt_main()
292
SmartTCPServer.hooks.install_named_hook(
293
'server_started_ex', on_server_start,
294
'run_bzr_serve_then_func hook')
297
self.run_bzr(['serve'] + list(serve_args))
298
except KeyboardInterrupt:
301
def when_server_started(self):
302
# Connect to the TCP server and issue some requests and see what comes
304
client_medium = medium.SmartTCPClientMedium(
305
'127.0.0.1', self.tcp_server.port,
306
'bzr://localhost:%d/' % (self.tcp_server.port,))
307
smart_client = client._SmartClient(client_medium)
308
resp = smart_client.call('mkdir', 'foo', '')
309
resp = smart_client.call('BzrDirFormat.initialize', 'foo/')
311
resp = smart_client.call('BzrDir.find_repositoryV3', 'foo/')
312
except errors.ErrorFromSmartServer, e:
314
self.client_resp = resp
315
client_medium.disconnect()