Merge lp:~coreygoldberg/selenium-simple-test/selftest-server-port2 into lp:selenium-simple-test

Proposed by Corey Goldberg
Status: Merged
Approved by: Vincent Ladeuil
Approved revision: 379
Merged at revision: 373
Proposed branch: lp:~coreygoldberg/selenium-simple-test/selftest-server-port2
Merge into: lp:selenium-simple-test
Diff against target: 338 lines (+114/-40)
9 files modified
src/sst/__init__.py (+2/-0)
src/sst/actions.py (+2/-2)
src/sst/scripts/run.py (+23/-14)
src/sst/selftests/assert_urls.py (+11/-11)
src/sst/selftests/current_url.py (+5/-4)
src/sst/selftests/html5.py (+2/-1)
src/sst/selftests/title.py (+9/-8)
src/sst/tests/__init__.py (+16/-0)
src/sst/tests/test_django_devserver.py (+44/-0)
To merge this branch: bzr merge lp:~coreygoldberg/selenium-simple-test/selftest-server-port2
Reviewer Review Type Date Requested Status
Corey Goldberg (community) Approve
Vincent Ladeuil (community) Approve
Review via email: mp+158256@code.launchpad.net

Commit message

default django devserver port changed to 8120 and better error handling

Description of the change

default port is now: 8120
if port is in use, it quits with less cryptic "port is in use" error.

To post a comment you must log in.
375. By Corey Goldberg

added back missing import

376. By Corey Goldberg

fixed whitespace

Revision history for this message
Vincent Ladeuil (vila) wrote :

Could you please use DEVSERVERPORT everywhere instead of using the hardcoded 8120 value ? Otherwise changing that value in sst/__init__.py won't make the tests pass.

While there, I think we would even want to use an URL instead of just the port so that we won't have to redo the same work if something similar happen with the hostname.

80 + for desc, cmd, arg in cleanups:

This forces all users to add a needless 'None' parameter when using cleanups while not allowing several parameters to be used if needed. I would rather use cmd(*args) below:

 88 + cmd(arg)

this will also clarify the proposal by avoiding the added parameter for code not directly related to this fix.

204 +def check_devserver_port_used(port):
205 + """check if port is ok to use for django devserver"""

This relies on django using the same SO_REUSEADDR trick, I think it's worth a comment.

Alternatively, you could check that the django server itself is properly running by checking a specific url defined for that purpose in our test application.

review: Needs Fixing
377. By Corey Goldberg

fix per MP review. paramaterized acceptance test with DEVSERVER_PORT

378. By Corey Goldberg

fixed hardcoded devserver ports in acceptance tests

Revision history for this message
Corey Goldberg (coreygoldberg) wrote :

fixed per review comments.
also found more hardcoded ports in acceptance tests and fixed (all or converted to parameter for port now).

all unit and acceptance tests run clean.

review: Needs Resubmitting
379. By Corey Goldberg

fixed port parameters for deverserver in unit test

Revision history for this message
Vincent Ladeuil (vila) wrote :

Far better, let's land this.

review: Approve
Revision history for this message
Corey Goldberg (coreygoldberg) :
review: Approve
Revision history for this message
Corey Goldberg (coreygoldberg) wrote :

landing it now. thanks vila!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/sst/__init__.py'
2--- src/sst/__init__.py 2013-01-24 06:02:56 +0000
3+++ src/sst/__init__.py 2013-04-11 14:32:21 +0000
4@@ -19,3 +19,5 @@
5
6
7 __version__ = '0.2.3dev'
8+
9+DEVSERVER_PORT = '8120' # django devserver for internal acceptance tests
10
11=== modified file 'src/sst/actions.py'
12--- src/sst/actions.py 2013-04-09 16:07:17 +0000
13+++ src/sst/actions.py 2013-04-11 14:32:21 +0000
14@@ -62,7 +62,7 @@
15
16 from sst import config
17 from sst import bmobproxy
18-
19+from sst import DEVSERVER_PORT
20
21 __all__ = [
22 'accept_alert', 'add_cleanup', 'assert_attribute', 'assert_button',
23@@ -96,7 +96,7 @@
24 _check_flags = True
25 _test = None
26
27-BASE_URL = 'http://localhost:8000/'
28+BASE_URL = 'http://localhost:%s/' % DEVSERVER_PORT
29 __DEFAULT_BASE_URL__ = BASE_URL
30
31 logger = logging.getLogger('SST')
32
33=== modified file 'src/sst/scripts/run.py'
34--- src/sst/scripts/run.py 2013-03-19 02:55:05 +0000
35+++ src/sst/scripts/run.py 2013-04-11 14:32:21 +0000
36@@ -29,7 +29,7 @@
37 import urllib
38
39 import sst
40-from sst import runtests
41+from sst import runtests, tests
42 from sst.command import get_opts_run, clear_old_results
43
44
45@@ -55,8 +55,13 @@
46
47 if cmd_opts.run_tests:
48 cmd_opts.dir_name = 'selftests'
49- run_django()
50- cleanups.append(('\nkilling django...', kill_django))
51+ if not tests.check_devserver_port_used(sst.DEVSERVER_PORT):
52+ run_django(sst.DEVSERVER_PORT)
53+ cleanups.append(('\nkilling django...', kill_django, sst.DEVSERVER_PORT))
54+ else:
55+ print 'Error: port is in use.'
56+ print 'can not launch devserver for internal tests.'
57+ sys.exit(1)
58
59 if cmd_opts.xserver_headless:
60 from sst.xvfbdisplay import Xvfb
61@@ -100,19 +105,22 @@
62 finally:
63
64 print '--------------------------------------------------------------'
65- for desc, cmd in cleanups:
66- # Run cleanups, displaying but not propagating exceptions
67+ for cleanup in cleanups:
68+ # run cleanups, displaying but not propagating exceptions
69+ desc = cleanup[0]
70+ cmd = cleanup[1]
71+ args = cleanup[2:]
72+ print desc
73 try:
74- print desc
75- cmd()
76+ cmd(*args)
77 except Exception:
78 print traceback.format_exc()
79
80
81-def run_django():
82+def run_django(port):
83 """Start django server for running local self-tests."""
84 manage_file = './src/testproject/manage.py'
85- url = 'http://localhost:8000/'
86+ url = 'http://localhost:%s/' % port
87
88 if not os.path.isfile(manage_file):
89 print 'Error: can not find the django testproject.'
90@@ -125,7 +133,7 @@
91 print 'Error: can not find django module.'
92 print 'you must have django installed to run the test project.'
93 sys.exit(1)
94- subprocess.Popen([manage_file, 'runserver'],
95+ proc = subprocess.Popen([manage_file, 'runserver', port],
96 stderr=open(os.devnull, 'w'),
97 stdout=open(os.devnull, 'w')
98 )
99@@ -143,11 +151,12 @@
100 print 'Error: can not get response from %r' % url
101 raise
102 print 'django found. continuing...'
103-
104-
105-def kill_django():
106+ return proc
107+
108+
109+def kill_django(port):
110 try:
111- urllib.urlopen('http://localhost:8000/kill_django')
112+ urllib.urlopen('http://localhost:%s/kill_django' % port)
113 except IOError:
114 pass
115
116
117=== modified file 'src/sst/selftests/assert_urls.py'
118--- src/sst/selftests/assert_urls.py 2013-04-08 14:50:11 +0000
119+++ src/sst/selftests/assert_urls.py 2013-04-11 14:32:21 +0000
120@@ -1,27 +1,27 @@
121 from sst.actions import *
122+from sst import DEVSERVER_PORT
123+
124 from urlparse import urlparse
125
126
127-assert_equal(get_base_url(), 'http://localhost:8000/')
128-
129 # haven't visited a url yet, so all assert_url* fail
130-fails(assert_url, 'http://localhost:8000/')
131+fails(assert_url, 'http://localhost:%s/' % DEVSERVER_PORT)
132 fails(assert_url_contains, 'localhost')
133 fails(assert_url_network_location, 'localhost')
134
135 # now visit a url and test assertions
136-go_to('/begin')
137+go_to('%sbegin' % get_base_url())
138
139 assert_url('/begin')
140 assert_url('/begin/')
141 assert_url('begin/')
142-assert_url('http://localhost:8000/begin')
143-assert_url('http://localhost:8000/begin/')
144+assert_url('http://localhost:%s/begin' % DEVSERVER_PORT)
145+assert_url('http://localhost:%s/begin/' % DEVSERVER_PORT)
146 assert_url(urlparse('http://wrongurl/begin').path)
147 fails(assert_url, 'http://wrongurl/begin')
148
149-assert_url_contains('http://localhost:8000/begin')
150-assert_url_contains('localhost:8000')
151+assert_url_contains('http://localhost:%s/begin' % DEVSERVER_PORT)
152+assert_url_contains('localhost:%s' % DEVSERVER_PORT)
153 assert_url_contains('.*/begin', regex=True)
154 assert_url_contains('http://.*/begin', regex=True)
155 assert_url_contains('.*//localhost', regex=True)
156@@ -29,14 +29,14 @@
157 fails(assert_url_contains, 'foobar')
158 fails(assert_url_contains, 'foobar', regex=True)
159
160-assert_url_network_location('localhost:8000')
161+assert_url_network_location('localhost:%s' % DEVSERVER_PORT)
162 fails(assert_url_network_location, 'localhost')
163 fails(assert_url_network_location, '')
164
165 # visit url with query strings and fragments, then test assertions
166 go_to('/begin?query_string#fragment_id')
167
168-assert_url('http://localhost:8000/begin?query_string#fragment_id')
169+assert_url('http://localhost:%s/begin?query_string#fragment_id' % DEVSERVER_PORT)
170 assert_url('/begin?query_string#fragment_id')
171 fails(assert_url, '/begin')
172-fails(assert_url, 'http://localhost:8000/begin')
173+fails(assert_url, 'http://localhost:%s/begin' % DEVSERVER_PORT)
174
175=== modified file 'src/sst/selftests/current_url.py'
176--- src/sst/selftests/current_url.py 2012-08-27 14:49:57 +0000
177+++ src/sst/selftests/current_url.py 2013-04-11 14:32:21 +0000
178@@ -1,13 +1,14 @@
179 from sst.actions import *
180+from sst import DEVSERVER_PORT
181
182 go_to('/')
183 url = get_current_url()
184 base_url = get_base_url()
185-assert_equal(base_url, 'http://localhost:8000/')
186-assert_equal(url, 'http://localhost:8000/')
187+assert_equal(base_url, 'http://localhost:%s/' % DEVSERVER_PORT)
188+assert_equal(url, 'http://localhost:%s/' % DEVSERVER_PORT)
189
190 go_to('/begin')
191 url = get_current_url()
192 base_url = get_base_url()
193-assert_equal(base_url, 'http://localhost:8000/')
194-assert_equal(url, 'http://localhost:8000/begin')
195+assert_equal(base_url, 'http://localhost:%s/' % DEVSERVER_PORT)
196+assert_equal(url, 'http://localhost:%s/begin' % DEVSERVER_PORT)
197
198=== modified file 'src/sst/selftests/html5.py'
199--- src/sst/selftests/html5.py 2011-12-07 19:35:25 +0000
200+++ src/sst/selftests/html5.py 2013-04-11 14:32:21 +0000
201@@ -1,4 +1,5 @@
202 from sst.actions import *
203+from sst import DEVSERVER_PORT
204
205 go_to('/html5')
206
207@@ -6,7 +7,7 @@
208 write_textfield('email', 'foo@bar.com', check=True)
209
210 assert_textfield('url')
211-write_textfield('url', 'http://localhost:8000', check=True)
212+write_textfield('url', 'http://localhost:%s' % DEVSERVER_PORT, check=True)
213
214 assert_textfield('search')
215 write_textfield('search', 'something', check=True)
216
217=== modified file 'src/sst/selftests/title.py'
218--- src/sst/selftests/title.py 2012-08-27 16:11:28 +0000
219+++ src/sst/selftests/title.py 2013-04-11 14:32:21 +0000
220@@ -1,4 +1,5 @@
221 from sst.actions import *
222+from sst import DEVSERVER_PORT
223
224 # tests go_to, assert_url, assert_title, set_base_url
225 # reset_base_url, get_base_url
226@@ -15,24 +16,24 @@
227 assert_title_contains('.*Pag[E|e]', regex=True)
228 fails(assert_title_contains, 'foobar')
229
230-set_base_url('localhost:8000')
231-assert get_base_url() == 'http://localhost:8000'
232+set_base_url('localhost:%s' % DEVSERVER_PORT)
233+assert get_base_url() == 'http://localhost:%s' % DEVSERVER_PORT
234
235-set_base_url('http://localhost:8000/')
236-assert get_base_url() == 'http://localhost:8000/'
237+set_base_url('http://localhost:%s/' % DEVSERVER_PORT)
238+assert get_base_url() == 'http://localhost:%s/' % DEVSERVER_PORT
239 go_to('/')
240
241 # assert_url adds the base url for relative urls
242 # so test both ways
243-assert_url('http://localhost:8000/')
244+assert_url('http://localhost:%s/' % DEVSERVER_PORT)
245 assert_url('/')
246
247 fails(assert_url, '/begin/')
248
249 reset_base_url()
250-assert get_base_url() == 'http://localhost:8000/'
251+assert get_base_url() == 'http://localhost:%s/' % DEVSERVER_PORT
252 go_to('/')
253-assert_url('http://localhost:8000/')
254+assert_url('http://localhost:%s/' % DEVSERVER_PORT)
255
256 # assert_url works also without the trailing slash
257-assert_url('http://localhost:8000')
258+assert_url('http://localhost:%s' % DEVSERVER_PORT)
259
260=== modified file 'src/sst/tests/__init__.py'
261--- src/sst/tests/__init__.py 2013-01-24 06:16:28 +0000
262+++ src/sst/tests/__init__.py 2013-04-11 14:32:21 +0000
263@@ -18,6 +18,7 @@
264
265 import os
266 import shutil
267+import socket
268 import tempfile
269
270 from sst import runtests
271@@ -45,3 +46,18 @@
272 current_dir = os.getcwdu()
273 test.addCleanup(os.chdir, current_dir)
274 os.chdir(test.test_base_dir)
275+
276+
277+def check_devserver_port_used(port):
278+ """check if port is ok to use for django devserver"""
279+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
280+ # immediately reuse a local socket in TIME_WAIT state
281+ sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
282+ try:
283+ sock.bind(('127.0.0.1', int(port)))
284+ used = False
285+ except socket.error as e:
286+ used = True
287+ finally:
288+ sock.close()
289+ return used
290
291=== added file 'src/sst/tests/test_django_devserver.py'
292--- src/sst/tests/test_django_devserver.py 1970-01-01 00:00:00 +0000
293+++ src/sst/tests/test_django_devserver.py 2013-04-11 14:32:21 +0000
294@@ -0,0 +1,44 @@
295+#
296+# Copyright (c) 2013 Canonical Ltd.
297+#
298+# This file is part of: SST (selenium-simple-test)
299+# https://launchpad.net/selenium-simple-test
300+#
301+# Licensed under the Apache License, Version 2.0 (the "License");
302+# you may not use this file except in compliance with the License.
303+# You may obtain a copy of the License at
304+#
305+# http://www.apache.org/licenses/LICENSE-2.0
306+#
307+# Unless required by applicable law or agreed to in writing, software
308+# distributed under the License is distributed on an "AS IS" BASIS,
309+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
310+# See the License for the specific language governing permissions and
311+# limitations under the License.
312+#
313+
314+
315+import testtools
316+
317+from sst.scripts import run
318+from sst.tests import check_devserver_port_used
319+from sst import DEVSERVER_PORT
320+
321+
322+class TestDjangoDevServer(testtools.TestCase):
323+
324+ def test_django_start(self):
325+ self.addCleanup(run.kill_django, DEVSERVER_PORT)
326+ proc = run.run_django(DEVSERVER_PORT)
327+ self.assertIsNotNone(proc)
328+
329+
330+ def test_django_devserver_port_used(self):
331+ used = check_devserver_port_used(DEVSERVER_PORT)
332+ self.assertFalse(used)
333+
334+ self.addCleanup(run.kill_django, DEVSERVER_PORT)
335+ run.run_django(DEVSERVER_PORT)
336+
337+ used = check_devserver_port_used(DEVSERVER_PORT)
338+ self.assertTrue(used)

Subscribers

People subscribed via source and target branches