1
# Copyright (C) 2006 Canonical Ltd
1
# Copyright (C) 2006 by Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
29
revision as _mod_revision,
25
from bzrlib import errors
31
26
from bzrlib.branch import Branch
32
27
from bzrlib.bzrdir import BzrDir
33
28
from bzrlib.errors import ParamikoNotPresent
34
from bzrlib.smart import medium
35
29
from bzrlib.tests import TestCaseWithTransport, TestSkipped
36
from bzrlib.transport import get_transport, remote
30
from bzrlib.transport import get_transport, smart
33
class DoesNotCloseStdOutClient(smart.SmartStreamClient):
34
"""A client that doesn't close stdout upon disconnect().
36
We wish to let stdout remain open so that we can see if the server writes
37
anything to stdout during its shutdown.
42
self._connected = False
43
# The client's out is the server's in.
39
47
class TestBzrServe(TestCaseWithTransport):
41
def assertInetServerShutsdownCleanly(self, process):
49
def assertInetServerShutsdownCleanly(self, client, process):
42
50
"""Shutdown the server process looking for errors."""
43
# Shutdown the server: the server should shut down when it cannot read
51
# Disconnect the client forcefully JUST IN CASE because of __del__'s use
52
# in the smart module.
55
# Shutdown the server: the client should have disconnected cleanly and
56
# closed stdin, so the server process should shut itself down.
57
self.assertTrue(process.stdin.closed)
46
58
# Hide stdin from the subprocess module, so it won't fail to close it.
47
59
process.stdin = None
48
result = self.finish_bzr_subprocess(process)
60
result = self.finish_bzr_subprocess(process, retcode=0)
49
61
self.assertEqual('', result[0])
50
62
self.assertEqual('', result[1])
70
82
# Connect to the server
71
83
# We use this url because while this is no valid URL to connect to this
72
84
# server instance, the transport needs a URL.
73
client_medium = medium.SmartSimplePipesClientMedium(
74
process.stdout, process.stdin)
75
transport = remote.RemoteTransport(
76
'bzr://localhost/', medium=client_medium)
77
return process, transport
85
client = DoesNotCloseStdOutClient(
86
lambda: (process.stdout, process.stdin))
87
transport = smart.SmartTransport('bzr://localhost/', client=client)
88
return process, client, transport
79
90
def start_server_port(self, extra_options=()):
80
91
"""Start a bzr server subprocess.
96
107
def test_bzr_serve_inet_readonly(self):
97
108
"""bzr server should provide a read only filesystem by default."""
98
process, transport = self.start_server_inet()
109
process, client, transport = self.start_server_inet()
99
110
self.assertRaises(errors.TransportNotPossible, transport.mkdir, 'adir')
100
self.assertInetServerShutsdownCleanly(process)
111
# finish with the transport
113
self.assertInetServerShutsdownCleanly(client, process)
102
115
def test_bzr_serve_inet_readwrite(self):
104
117
self.make_branch('.')
106
process, transport = self.start_server_inet(['--allow-writes'])
119
process, client, transport = self.start_server_inet(['--allow-writes'])
108
121
# We get a working branch
109
122
branch = BzrDir.open_from_transport(transport).open_branch()
110
123
branch.repository.get_revision_graph()
111
self.assertEqual(_mod_revision.NULL_REVISION,
112
_mod_revision.ensure_null(branch.last_revision()))
113
self.assertInetServerShutsdownCleanly(process)
124
self.assertEqual(None, branch.last_revision())
126
# finish with the transport
129
self.assertInetServerShutsdownCleanly(client, process)
115
131
def test_bzr_serve_port_readonly(self):
116
132
"""bzr server should provide a read only filesystem by default."""
131
147
# We get a working branch
132
148
branch.repository.get_revision_graph()
133
self.assertEqual(_mod_revision.NULL_REVISION,
134
_mod_revision.ensure_null(branch.last_revision()))
149
self.assertEqual(None, branch.last_revision())
136
151
self.assertServerFinishesCleanly(process)
153
def test_bzr_serve_no_args(self):
154
"""'bzr serve' with no arguments or options should not traceback."""
155
out, err = self.run_bzr_error(
156
['bzr serve requires one of --inet or --port'], 'serve')
138
158
def test_bzr_connect_to_bzr_ssh(self):
139
159
"""User acceptance that get_transport of a bzr+ssh:// behaves correctly.
197
217
# Access the branch via a bzr+ssh URL. The BZR_REMOTE_PATH environment
198
218
# variable is used to tell bzr what command to run on the remote end.
199
path_to_branch = osutils.abspath('a_branch')
219
path_to_branch = os.path.abspath('a_branch')
201
221
orig_bzr_remote_path = os.environ.get('BZR_REMOTE_PATH')
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
222
os.environ['BZR_REMOTE_PATH'] = self.get_bzr_path()
207
if sys.platform == 'win32':
208
path_to_branch = os.path.splitdrive(path_to_branch)[1]
209
224
branch = Branch.open(
210
225
'bzr+ssh://fred:secret@localhost:%d%s' % (port, path_to_branch))
212
227
branch.repository.get_revision_graph()
213
self.assertEqual(_mod_revision.NULL_REVISION,
214
_mod_revision.ensure_null(branch.last_revision()))
228
self.assertEqual(None, branch.last_revision())
215
229
# Check we can perform write operations
216
230
branch.bzrdir.root_transport.mkdir('foo')