Merge lp://qastaging/~thisfred/desktopcouch/any_port_in_a_storm into lp://qastaging/desktopcouch

Proposed by Eric Casteleijn
Status: Merged
Approved by: Eric Casteleijn
Approved revision: 47
Merged at revision: not available
Proposed branch: lp://qastaging/~thisfred/desktopcouch/any_port_in_a_storm
Merge into: lp://qastaging/desktopcouch
Diff against target: None lines
To merge this branch: bzr merge lp://qastaging/~thisfred/desktopcouch/any_port_in_a_storm
Reviewer Review Type Date Requested Status
Stuart Langridge (community) Approve
Chad Miller (community) Approve
Review via email: mp+10628@code.qastaging.launchpad.net

Commit message

Reads the portnumber from the logfile, now that it is written there by couchdb.

To post a comment you must log in.
Revision history for this message
Eric Casteleijn (thisfred) wrote :

This reads the portnumber the user's couchdb is running on from the logfile, now that couchdb writes it there. Not pretty, but less complicated at least. Stupider is better than smarter.

46. By Eric Casteleijn

non premature optimization as suggested by Chad

47. By Eric Casteleijn

return None when not found

Revision history for this message
Chad Miller (cmiller) wrote :

Good, thank you.

review: Approve
Revision history for this message
Stuart Langridge (sil) wrote :

Looks good (and way simpler!) to me.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'desktopcouch/__init__.py'
2--- desktopcouch/__init__.py 2009-08-21 21:57:37 +0000
3+++ desktopcouch/__init__.py 2009-08-24 20:42:37 +0000
4@@ -16,7 +16,7 @@
5 "Desktop Couch helper files"
6
7 from __future__ import with_statement
8-import os, re, time
9+import os, time
10
11
12 def find_pid(start_if_not_running=True):
13@@ -80,61 +80,19 @@
14
15 return True
16
17-
18-def find_port__linux(pid):
19- # Look in the CouchDB log to find the port number, someday.
20- # Currently, we have to grovel around in /proc instead.
21- # Oh, the huge manatee... (this replaced an lsof shell recipe
22- # which was shorter but less reliable)
23-
24- proc_dir = "/proc/%s" % (pid,)
25-
26- # enumerate the process' file descriptors
27- fd_dir = os.path.join(proc_dir, 'fd')
28- try:
29- fd_paths = [os.readlink(os.path.join(fd_dir, fd))
30- for fd in os.listdir(fd_dir)]
31- except OSError:
32- raise RuntimeError("Unable to find file descriptors in /proc")
33-
34-
35- # identify socket fds
36- socket_matches = [re.match('socket:\\[([0-9]+)\\]', p) for p in fd_paths]
37- # extract their inode numbers
38- socket_inodes = [m.group(1) for m in socket_matches if m is not None]
39-
40- # construct a subexpression which matches any one of these inodes
41- inode_subexp = "|".join(socket_inodes)
42- # construct regexp to match /proc/net/tcp entries which are listening
43- # sockets having one of the given inode numbers
44- listening_regexp = re.compile(r'''
45- \s*\d+:\s* # sl
46- 0100007F:([0-9A-F]{4})\s+ # local_address
47- 00000000:0000\s+ # rem_address
48- 0A\s+ # st (0A = listening)
49- [0-9A-F]{8}: # tx_queue
50- [0-9A-F]{8}\s+ # rx_queue
51- [0-9A-F]{2}: # tr
52- [0-9A-F]{8}\s+ # tm->when
53- [0-9A-F]{8}\s* # retrnsmt
54- \d+\s+\d+\s+ # uid, timeout
55- (?:%s)\s+ # inode
56- ''' % (inode_subexp,), re.VERBOSE)
57-
58- # extract the TCP port from the first matching line in /proc/$pid/net/tcp
59- port = None
60- with open(os.path.join(proc_dir, 'net', 'tcp')) as tcp_file:
61- for line in tcp_file:
62- match = listening_regexp.match(line)
63- if match is not None:
64- port = str(int(match.group(1), 16))
65+def find_port():
66+ """Look in the CouchDB log to find the port number."""
67+
68+ from desktopcouch.local_files import FILE_LOG
69+ with open(FILE_LOG, 'r') as log_file:
70+ port = None
71+ for line in reversed(log_file.readlines()):
72+ if 'Apache CouchDB has started on http://' in line:
73+ port = line.split(':')[-1].strip()
74+ if port.endswith('/'):
75+ port = port[:-1]
76 break
77- if port is None:
78- raise RuntimeError("Unable to find listening port")
79-
80- return port
81-
82-
83+ return int(port)
84
85 import platform
86 os_name = platform.system()
87@@ -142,9 +100,5 @@
88 process_is_couchdb = {
89 "Linux": process_is_couchdb__linux
90 } [os_name]
91-
92- find_port = {
93- "Linux": find_port__linux
94- } [os_name]
95 except KeyError:
96 raise NotImplementedError("os %r is not yet supported" % (os_name,))
97
98=== modified file 'desktopcouch/contacts/contactspicker.py'
99--- desktopcouch/contacts/contactspicker.py 2009-08-22 17:22:02 +0000
100+++ desktopcouch/contacts/contactspicker.py 2009-08-24 20:35:25 +0000
101@@ -19,17 +19,15 @@
102 """A widget to allow users to pick contacts"""
103
104 import gtk
105-from desktopcouch.contacts.record import (
106- Contact,
107- CONTACT_RECORD_TYPE)
108+from desktopcouch.contacts.record import CONTACT_RECORD_TYPE
109 from desktopcouch.records.couchgrid import CouchGrid
110
111+
112 class ContactsPicker(gtk.VBox):
113+ """A contacts picker"""
114
115- def __init__(self):
116- """Create a new ContactsPicker widget
117-
118- """
119+ def __init__(self, uri=None):
120+ """Create a new ContactsPicker widget."""
121
122 gtk.VBox.__init__(self)
123
124@@ -40,11 +38,12 @@
125 self.search_entry = gtk.Entry()
126 hbox.pack_start(self.search_entry, True, True, 3)
127
128- self.search_button = gtk.Button(stock=gtk.STOCK_FIND, use_underline=True)
129+ self.search_button = gtk.Button(
130+ stock=gtk.STOCK_FIND, use_underline=True)
131 hbox.pack_start(self.search_button, False, False, 3)
132
133 # Create CouchGrid to contain list of contacts
134- self.contacts_list = CouchGrid('contacts')
135+ self.contacts_list = CouchGrid('contacts', uri=uri)
136 self.contacts_list.editable = False
137 self.contacts_list.keys = [ "first_name", "last_name" ]
138 self.contacts_list.record_type = CONTACT_RECORD_TYPE
139
140=== modified file 'desktopcouch/contacts/tests/test_contactspicker.py'
141--- desktopcouch/contacts/tests/test_contactspicker.py 2009-08-22 17:22:02 +0000
142+++ desktopcouch/contacts/tests/test_contactspicker.py 2009-08-24 20:35:25 +0000
143@@ -21,10 +21,24 @@
144 import testtools
145 import gtk
146 from desktopcouch.contacts.contactspicker import ContactsPicker
147+from desktopcouch.records.server import CouchDatabase
148+from desktopcouch.records.tests import get_uri
149+
150+URI = get_uri()
151
152 class TestContactsPicker(testtools.TestCase):
153 """Test the Contact Picker Window."""
154
155+ def setUp(self):
156+ """setup each test"""
157+ # Connect to CouchDB server
158+ self.dbname = 'contacts'
159+ self.database = CouchDatabase(self.dbname, create=True, uri=URI)
160+
161+ def tearDown(self):
162+ """tear down each test"""
163+ del self.database._server[self.dbname]
164+
165 def test_can_contruct_contactspicker(self):
166 """Test that we can build the window"""
167 # Create and show a test window
168@@ -34,8 +48,8 @@
169 win.resize(300, 450)
170
171 # Create the contacts picker widget
172- picker = ContactsPicker()
173+ picker = ContactsPicker(uri=URI)
174 win.get_content_area().pack_start(picker, True, True, 3)
175- self.assert_(picker.get_contacts_list())
176+ self.assert_(picker.get_contacts_list())
177
178
179
180=== modified file 'desktopcouch/records/server.py'
181--- desktopcouch/records/server.py 2009-08-21 22:45:24 +0000
182+++ desktopcouch/records/server.py 2009-08-24 20:35:25 +0000
183@@ -49,8 +49,8 @@
184
185 def __init__(self, database, uri=None, record_factory=None, create=False):
186 if not uri:
187- pid = desktopcouch.find_pid()
188- port = desktopcouch.find_port(pid)
189+ desktopcouch.find_pid()
190+ port = desktopcouch.find_port()
191 self.server_uri = "http://localhost:%s" % port
192 else:
193 self.server_uri = uri
194
195=== modified file 'desktopcouch/records/tests/__init__.py'
196--- desktopcouch/records/tests/__init__.py 2009-08-21 22:47:25 +0000
197+++ desktopcouch/records/tests/__init__.py 2009-08-24 20:35:25 +0000
198@@ -15,26 +15,36 @@
199 # along with desktopcouch. If not, see <http://www.gnu.org/licenses/>.
200 """Tests for Documents API"""
201
202-import os, tempfile
203-from desktopcouch.local_files import COUCH_EXE, couch_chain_flag
204+import os, tempfile, time, urllib2
205+from desktopcouch import local_files
206 from desktopcouch.start_local_couchdb import create_ini_file, run_couchdb
207
208 directory = tempfile.mkdtemp()
209-ini_path = os.path.join(directory, "test_couchdb.ini")
210-log_path = os.path.join(directory, "test_couchdb.log")
211-pid_path = os.path.join(directory, "test_couchdb.pid")
212-stdout_path = os.path.join(directory, "test_couchdb.stdout")
213-stderr_path = os.path.join(directory, "test_couchdb.stderr")
214-
215-db_dir = os.path.join(directory, "test_couchdb")
216-os.mkdir(db_dir)
217-
218-port = "21224"
219-create_ini_file(
220- ini_path=ini_path, db_dir=db_dir, log_path=log_path, port=port)
221-exec_command = [
222- COUCH_EXE, couch_chain_flag(), ini_path, '-p', pid_path, '-o', stdout_path,
223- '-e', stderr_path]
224-exec_command[2] = ini_path
225-run_couchdb(exec_command=exec_command)
226-URI = "htpp://localhost:%s" % port
227+local_files.FILE_INI = os.path.join(directory, "test_couchdb.ini")
228+local_files.FILE_LOG = os.path.join(directory, "test_couchdb.log")
229+local_files.FILE_PID = os.path.join(directory, "test_couchdb.pid")
230+local_files.FILE_STDOUT = os.path.join(directory, "test_couchdb.stdout")
231+local_files.FILE_STDERR = os.path.join(directory, "test_couchdb.stderr")
232+
233+local_files.DIR_DB = os.path.join(directory, "test_couchdb")
234+os.mkdir(local_files.DIR_DB)
235+
236+PORT = "21224"
237+create_ini_file(port=PORT)
238+local_files.COUCH_EXEC_COMMAND = [
239+ local_files.COUCH_EXE, local_files.couch_chain_flag(), local_files.FILE_INI,
240+ '-p', local_files.FILE_PID, '-o', local_files.FILE_STDOUT, '-e',
241+ local_files.FILE_STDERR]
242+run_couchdb()
243+
244+def get_uri():
245+ uri = 'http://localhost:%s' % PORT
246+ i = 0
247+ while i < 100:
248+ try:
249+ urllib2.urlopen(uri)
250+ break
251+ except:
252+ time.sleep(0.1)
253+ i += 1
254+ return uri
255
256=== modified file 'desktopcouch/records/tests/test_couchgrid.py'
257--- desktopcouch/records/tests/test_couchgrid.py 2009-08-22 17:22:02 +0000
258+++ desktopcouch/records/tests/test_couchgrid.py 2009-08-24 20:35:25 +0000
259@@ -22,8 +22,9 @@
260 from desktopcouch.records.record import Record
261 from desktopcouch.records.server import CouchDatabase
262 from desktopcouch.records.couchgrid import CouchGrid
263-from desktopcouch.records.tests import URI
264+from desktopcouch.records.tests import get_uri
265
266+URI = get_uri()
267
268 class TestCouchGrid(TestCase):
269 """Test the CouchGrid functionality"""
270
271=== modified file 'desktopcouch/records/tests/test_server.py'
272--- desktopcouch/records/tests/test_server.py 2009-08-21 22:45:24 +0000
273+++ desktopcouch/records/tests/test_server.py 2009-08-24 20:35:25 +0000
274@@ -20,7 +20,9 @@
275 import testtools
276 from desktopcouch.records.server import CouchDatabase
277 from desktopcouch.records.record import Record
278-from desktopcouch.records.tests import URI
279+from desktopcouch.records.tests import get_uri
280+
281+URI = get_uri()
282
283 FAKE_RECORD_TYPE = "http://example.org/test"
284
285
286=== modified file 'desktopcouch/start_local_couchdb.py'
287--- desktopcouch/start_local_couchdb.py 2009-08-21 22:45:24 +0000
288+++ desktopcouch/start_local_couchdb.py 2009-08-24 20:35:25 +0000
289@@ -56,12 +56,12 @@
290 fd.write("\n")
291 fd.close()
292
293-def create_ini_file(
294- ini_path=local_files.FILE_INI, db_dir=local_files.DIR_DB,
295- log_path=local_files.FILE_LOG, port="0"):
296+def create_ini_file(port="0"):
297 """Write CouchDB ini file if not already present"""
298+ ini_path = local_files.FILE_INI
299 if os.path.exists(ini_path):
300 return
301+ db_dir = local_files.DIR_DB
302 ini = {
303 'couchdb': {
304 'database_dir': db_dir,
305@@ -72,15 +72,15 @@
306 'port': port,
307 },
308 'log': {
309- 'file': log_path,
310+ 'file': local_files.FILE_LOG,
311 'level': 'info',
312 },
313 }
314 dump_ini(ini, ini_path)
315
316-def run_couchdb(exec_command=local_files.COUCH_EXEC_COMMAND):
317+def run_couchdb():
318 """Actually start the CouchDB process"""
319- local_exec = exec_command + ['-b']
320+ local_exec = local_files.COUCH_EXEC_COMMAND + ['-b']
321 try:
322 # subprocess is buggy. Chad patched, but that takes time to propagate.
323 proc = subprocess.Popen(local_exec)
324@@ -165,12 +165,12 @@
325 for retry in xrange(10000, 0, -1):
326 pid = desktopcouch.find_pid(start_if_not_running=False)
327 try:
328- port = desktopcouch.find_port(pid)
329+ port = desktopcouch.find_port()
330 break
331- except RuntimeError, e:
332+ except IOError:
333 if retry == 1:
334 raise
335- time.sleep(0.01)
336+ time.sleep(0.1)
337 continue
338
339 if port is None:
340@@ -193,8 +193,8 @@
341 run_couchdb()
342 # Note that we do not call update_design_documents here. This is because
343 # Couch won't actually have started yet, so when update_design_documents
344- # calls the Records API, that will call back into get_pid and we end up
345- # starting Couch again. Instead, get_pid calls update_design_documents
346+ # calls the Records API, that will call back into get_port and we end up
347+ # starting Couch again. Instead, get_port calls update_design_documents
348 # *after* Couch startup has occurred.
349 write_bookmark_file()
350

Subscribers

People subscribed via source and target branches