Merge lp:~jameinel/u1db/commandline into lp:u1db

Proposed by John A Meinel
Status: Merged
Merged at revision: 103
Proposed branch: lp:~jameinel/u1db/commandline
Merge into: lp:u1db
Diff against target: 186 lines (+171/-0)
3 files modified
u1db-serve (+50/-0)
u1db/tests/commandline/__init__.py (+15/-0)
u1db/tests/commandline/test_serve.py (+106/-0)
To merge this branch: bzr merge lp:~jameinel/u1db/commandline
Reviewer Review Type Date Requested Status
Samuele Pedroni Approve
Review via email: mp+80846@code.launchpad.net

Description of the change

This adds 'u1db-serve' as a way to start a U1DB TCPSyncServer instance.

There is some basic tests for it. I may need to tweak the code a bit, because I'm not sure if all of terminate/kill/etc exist on all platforms.

For now, I don't have a default port, but it will use a randomly generated one and tell you where it bound to.

To post a comment you must log in.
Revision history for this message
Stuart Langridge (sil) wrote :

Needs int(args.port), I think.

Revision history for this message
John A Meinel (jameinel) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 10/31/2011 10:53 PM, Stuart Langridge wrote:
> Needs int(args.port), I think.

I think I need "type=int" in the parser perhaps. But that is also what
test suites are for finding out :).

John
=:->

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk6vJKAACgkQJdeBCYSNAAMKOwCgz4XGywIMgCOshzjH1yGDDDuj
c6MAoMkFstd/RTXYrJFdtPVa1KgAI4CM
=6H+w
-----END PGP SIGNATURE-----

Revision history for this message
Samuele Pedroni (pedronis) wrote :

looks good but indeed -p port is not parsed as an int properly

review: Needs Fixing
Revision history for this message
John A Meinel (jameinel) wrote :

Updated to handle --port correctly, along with a test case.

lp:~jameinel/u1db/commandline updated
97. By John A Meinel

Update the code to properly handle --port

Revision history for this message
Samuele Pedroni (pedronis) wrote :

looks good, we need a way though to specify to listen not only on localhost (or the reverse)

review: Approve
Revision history for this message
John A Meinel (jameinel) wrote :

Bzr serve allows you to do it via the --port parameter. So you can say
--port localhost:4155

It doesn't seem like a great match, but also not something you set all the
time.

John
=:->
On Nov 2, 2011 7:16 AM, "Samuele Pedroni" <email address hidden>
wrote:

> Review: Approve
>
> looks good, we need a way though to specify to listen not only on
> localhost (or the reverse)
> --
> https://code.launchpad.net/~jameinel/u1db/commandline/+merge/80846
> You are the owner of lp:~jameinel/u1db/commandline.
>

Revision history for this message
John A Meinel (jameinel) wrote :

Oh, and I think the default should be 0.0.0.0, I was being conservative
with a prototype. Especially since it doesn't have innate auth yet.

John
=:->
On Nov 2, 2011 7:16 AM, "Samuele Pedroni" <email address hidden>
wrote:

> Review: Approve
>
> looks good, we need a way though to specify to listen not only on
> localhost (or the reverse)
> --
> https://code.launchpad.net/~jameinel/u1db/commandline/+merge/80846
> You are the owner of lp:~jameinel/u1db/commandline.
>

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'u1db-serve'
2--- u1db-serve 1970-01-01 00:00:00 +0000
3+++ u1db-serve 2011-11-01 14:02:24 +0000
4@@ -0,0 +1,50 @@
5+#!/usr/bin/env python
6+# Copyright 2011 Canonical Ltd.
7+#
8+# This program is free software: you can redistribute it and/or modify it
9+# under the terms of the GNU General Public License version 3, as published
10+# by the Free Software Foundation.
11+#
12+# This program is distributed in the hope that it will be useful, but
13+# WITHOUT ANY WARRANTY; without even the implied warranties of
14+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15+# PURPOSE. See the GNU General Public License for more details.
16+#
17+# You should have received a copy of the GNU General Public License along
18+# with this program. If not, see <http://www.gnu.org/licenses/>.
19+
20+import sys
21+from u1db import (
22+ __version__ as _u1db_version,
23+ )
24+from u1db.remote import (
25+ sync_server,
26+ requests,
27+ )
28+
29+
30+def main(args):
31+ import argparse
32+ p = argparse.ArgumentParser(usage='%(prog)s [options]',
33+ description='Run the U1DB server')
34+ p.add_argument('--version', action='version', version=_u1db_version)
35+ p.add_argument('--verbose', action='store_true', help='be chatty')
36+ p.add_argument('--port', '-p', default=0, metavar='PORT', type=int,
37+ help='Bind to this port when serving.')
38+
39+ args = p.parse_args(args)
40+
41+ state = requests.ServerState()
42+ state.set_workingdir('.')
43+ server = sync_server.TCPSyncServer(('127.0.0.1', args.port),
44+ sync_server.TCPSyncRequestHandler, state)
45+ sys.stdout.write('listening on port: %s\n' % (server.server_address[1],))
46+ sys.stdout.flush()
47+ server.serve_forever()
48+
49+
50+if __name__ == '__main__':
51+ sys.exit(main(sys.argv[1:]))
52+
53+
54+# vim: ft=python
55
56=== added directory 'u1db/tests/commandline'
57=== added file 'u1db/tests/commandline/__init__.py'
58--- u1db/tests/commandline/__init__.py 1970-01-01 00:00:00 +0000
59+++ u1db/tests/commandline/__init__.py 2011-11-01 14:02:24 +0000
60@@ -0,0 +1,15 @@
61+# Copyright 2011 Canonical Ltd.
62+#
63+# This program is free software: you can redistribute it and/or modify it
64+# under the terms of the GNU General Public License version 3, as published
65+# by the Free Software Foundation.
66+#
67+# This program is distributed in the hope that it will be useful, but
68+# WITHOUT ANY WARRANTY; without even the implied warranties of
69+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
70+# PURPOSE. See the GNU General Public License for more details.
71+#
72+# You should have received a copy of the GNU General Public License along
73+# with this program. If not, see <http://www.gnu.org/licenses/>.
74+
75+
76
77=== added file 'u1db/tests/commandline/test_serve.py'
78--- u1db/tests/commandline/test_serve.py 1970-01-01 00:00:00 +0000
79+++ u1db/tests/commandline/test_serve.py 2011-11-01 14:02:24 +0000
80@@ -0,0 +1,106 @@
81+# Copyright 2011 Canonical Ltd.
82+#
83+# This program is free software: you can redistribute it and/or modify it
84+# under the terms of the GNU General Public License version 3, as published
85+# by the Free Software Foundation.
86+#
87+# This program is distributed in the hope that it will be useful, but
88+# WITHOUT ANY WARRANTY; without even the implied warranties of
89+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
90+# PURPOSE. See the GNU General Public License for more details.
91+#
92+# You should have received a copy of the GNU General Public License along
93+# with this program. If not, see <http://www.gnu.org/licenses/>.
94+
95+import errno
96+import os
97+import socket
98+import subprocess
99+import sys
100+import time
101+
102+from u1db import (
103+ __version__ as _u1db_version,
104+ tests,
105+ )
106+from u1db.remote import client
107+
108+
109+def safe_close(process, timeout=0.1):
110+ """Shutdown the process in the nicest fashion you can manage.
111+
112+ :param process: A subprocess.Popen object.
113+ :param timeout: We'll try to send 'SIGTERM' but if the process is alive
114+ longer that 'timeout', we'll send SIGKILL.
115+ """
116+ if process.poll() is not None:
117+ return
118+ try:
119+ process.terminate()
120+ except OSError, e:
121+ if e.errno in (errno.ESRCH,):
122+ # Process has exited
123+ return
124+ tend = time.time() + timeout
125+ while time.time() < tend:
126+ if process.poll() is not None:
127+ return
128+ time.sleep(0.01)
129+ try:
130+ process.kill()
131+ except OSError, e:
132+ if e.errno in (errno.ESRCH,):
133+ # Process has exited
134+ return
135+ process.wait()
136+
137+
138+class TestU1DBServe(tests.TestCase):
139+
140+ def _get_u1db_serve_path(self):
141+ from u1db import __path__ as u1db_path
142+ u1db_parent_dir = os.path.dirname(u1db_path[0])
143+ return os.path.join(u1db_parent_dir, 'u1db-serve')
144+
145+ def startU1DBServe(self, args):
146+ command = [sys.executable, self._get_u1db_serve_path()]
147+ command.extend(args)
148+ p = subprocess.Popen(command, stdin=subprocess.PIPE,
149+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
150+ self.addCleanup(safe_close, p)
151+ return p
152+
153+ def test_help(self):
154+ p = self.startU1DBServe(['--help'])
155+ stdout, stderr = p.communicate()
156+ self.assertEqual('', stderr)
157+ self.assertEqual(0, p.returncode)
158+ self.assertIn('Run the U1DB server', stdout)
159+
160+ def test_bind_to_port(self):
161+ p = self.startU1DBServe([])
162+ starts = 'listening on port:'
163+ x = p.stdout.readline()
164+ self.assertTrue(x.startswith(starts))
165+ port = int(x[len(starts):])
166+ s = socket.socket()
167+ s.connect(('127.0.0.1', port))
168+ self.addCleanup(s.close)
169+ c = client.Client(s)
170+ self.assertEqual({'version': _u1db_version},
171+ c.call_returning_args('version'))
172+
173+ def test_supply_port(self):
174+ s = socket.socket()
175+ s.bind(('127.0.0.1', 0))
176+ host, port = s.getsockname()
177+ s.close()
178+ p = self.startU1DBServe(['--port', str(port)])
179+ x = p.stdout.readline()
180+ self.assertEqual('listening on port: %s\n' % (port,), x)
181+ s = socket.socket()
182+ s.connect(('127.0.0.1', port))
183+ self.addCleanup(s.close)
184+ c = client.Client(s)
185+ self.assertEqual({'version': _u1db_version},
186+ c.call_returning_args('version'))

Subscribers

People subscribed via source and target branches