Merge lp:~mandel/ubuntu-sso-client/fix-webclient-tests into lp:ubuntu-sso-client

Proposed by Manuel de la Peña
Status: Merged
Approved by: Manuel de la Peña
Approved revision: 967
Merged at revision: 946
Proposed branch: lp:~mandel/ubuntu-sso-client/fix-webclient-tests
Merge into: lp:ubuntu-sso-client
Prerequisite: lp:~mandel/ubuntu-sso-client/fix-broken-tests
Diff against target: 420 lines (+115/-155)
4 files modified
ubuntu_sso/utils/tests/test_common.py (+7/-22)
ubuntu_sso/utils/webclient/tests/__init__.py (+0/-94)
ubuntu_sso/utils/webclient/tests/test_timestamp.py (+7/-5)
ubuntu_sso/utils/webclient/tests/test_webclient.py (+101/-34)
To merge this branch: bzr merge lp:~mandel/ubuntu-sso-client/fix-webclient-tests
Reviewer Review Type Date Requested Status
Brian Curtin (community) Approve
Diego Sarmentero (community) Approve
Review via email: mp+101410@code.launchpad.net

Commit message

- Added the use of the new added webserver that cleans resources correctly (LP: #960436).

Description of the change

- Added the use of the new added webserver that cleans resources correctly (LP: #960436).

To post a comment you must log in.
959. By Manuel de la Peña

Link bug.

960. By Manuel de la Peña

Use connetionLost to get a deferred when we cleaned everything.

961. By Manuel de la Peña

Merged fix-broken-tests into fix-webclient-tests.

Revision history for this message
Diego Sarmentero (diegosarmentero) wrote :

+1

review: Approve
962. By Manuel de la Peña

Merged fix-broken-tests into fix-webclient-tests.

963. By Manuel de la Peña

Use the correct namespaces.

Revision history for this message
Brian Curtin (brian.curtin) wrote :

60 + # TODO: why do we need to use localhost and not just use the webserver
61 + # get_uri???

What does get_uri give? localhost does work work fine here.

review: Needs Information
964. By Manuel de la Peña

Merged fix-broken-tests into fix-webclient-tests.

965. By Manuel de la Peña

Updated branch to use the new API.

966. By Manuel de la Peña

Merged fix-broken-tests into fix-webclient-tests.

967. By Manuel de la Peña

Updated to use the new API.

Revision history for this message
Brian Curtin (brian.curtin) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ubuntu_sso/utils/tests/test_common.py'
2--- ubuntu_sso/utils/tests/test_common.py 2012-04-09 17:38:24 +0000
3+++ ubuntu_sso/utils/tests/test_common.py 2012-04-17 20:34:24 +0000
4@@ -33,11 +33,11 @@
5 import sys
6 import time
7
8-from twisted.application import internet, service
9 from twisted.internet import defer
10 from twisted.internet.threads import deferToThread
11-from twisted.web import server, resource
12+from twisted.web import resource
13 from ubuntuone.devtools.handlers import MementoHandler
14+from ubuntuone.devtools.testing.txwebserver import HTTPWebServer
15
16 from ubuntu_sso import utils
17 from ubuntu_sso.tests import TestCase, EMAIL, TOKEN
18@@ -306,30 +306,14 @@
19 return ""
20
21
22-class MockWebServer(object):
23+class MockWebServer(HTTPWebServer):
24 """A mock webserver for testing."""
25
26 def __init__(self):
27 """Start up this instance."""
28 # pylint: disable=E1101
29- self.root = RootResource()
30- site = server.Site(self.root)
31- application = service.Application('web')
32- self.service_collection = service.IServiceCollection(application)
33- self.tcpserver = internet.TCPServer(0, site)
34- self.tcpserver.setServiceParent(self.service_collection)
35- self.service_collection.startService()
36-
37- def get_url(self):
38- """Build the url for this mock server."""
39- # pylint: disable=W0212
40- port_num = self.tcpserver._port.getHost().port
41- return "http://localhost:%d/" % port_num
42-
43- def stop(self):
44- """Shut it down."""
45- # pylint: disable=E1101
46- self.service_collection.stopService()
47+ root = RootResource()
48+ super(MockWebServer, self).__init__(root)
49
50
51 class FakedError(Exception):
52@@ -344,8 +328,9 @@
53 """Initialize a fake webserver."""
54 yield super(TimestampCheckerTestCase, self).setUp()
55 self.ws = MockWebServer()
56+ self.ws.start()
57 self.addCleanup(self.ws.stop)
58- self.patch(SyncTimestampChecker, "SERVER_URL", self.ws.get_url())
59+ self.patch(SyncTimestampChecker, "SERVER_URL", self.ws.get_iri())
60
61 @defer.inlineCallbacks
62 def test_returned_value_is_int(self):
63
64=== modified file 'ubuntu_sso/utils/webclient/tests/__init__.py'
65--- ubuntu_sso/utils/webclient/tests/__init__.py 2012-04-09 17:38:24 +0000
66+++ ubuntu_sso/utils/webclient/tests/__init__.py 2012-04-17 20:34:24 +0000
67@@ -28,14 +28,6 @@
68 # files in the program, then also delete it here.
69 """Tests for the proxy-aware webclient."""
70
71-from twisted.application import internet, service
72-from twisted.internet import ssl
73-from twisted.web import http, server
74-
75-
76-# Some settings are not used as described in:
77-# https://bugzilla.gnome.org/show_bug.cgi?id=648237
78-
79 TEMPLATE_GSETTINGS_OUTPUT = """\
80 org.gnome.system.proxy autoconfig-url '{autoconfig_url}'
81 org.gnome.system.proxy ignore-hosts {ignore_hosts:s}
82@@ -69,89 +61,3 @@
83 "socks_host": "",
84 "socks_port": 0,
85 }
86-
87-
88-class SaveHTTPChannel(http.HTTPChannel):
89- """A save protocol to be used in tests."""
90-
91- protocolInstance = None
92-
93- # pylint: disable=C0103
94- def connectionMade(self):
95- """Keep track of the given protocol."""
96- SaveHTTPChannel.protocolInstance = self
97- http.HTTPChannel.connectionMade(self)
98-
99-
100-class SaveSite(server.Site):
101- """A site that let us know when it closed."""
102-
103- protocol = SaveHTTPChannel
104-
105- def __init__(self, *args, **kwargs):
106- """Create a new instance."""
107- server.Site.__init__(self, *args, **kwargs)
108- # we disable the timeout in the tests, we will deal with it manually.
109- # pylint: disable=C0103
110- self.timeOut = None
111-
112-
113-class BaseMockWebServer(object):
114- """A mock webserver for testing"""
115-
116- def __init__(self, ssl_settings=None):
117- """Start up this instance."""
118- self.root = self.get_root_resource()
119- self.site = SaveSite(self.root)
120- application = service.Application('web')
121- self.service_collection = service.IServiceCollection(application)
122- #pylint: disable=E1101
123- ssl_context = None
124- if (ssl_settings is not None
125- and 'key' in ssl_settings
126- and 'cert' in ssl_settings):
127- ssl_context = ssl.DefaultOpenSSLContextFactory(ssl_settings['key'],
128- ssl_settings['cert'])
129- self.ssl_server = internet.SSLServer(0, self.site, ssl_context)
130- else:
131- self.ssl_server = None
132- self.server = internet.TCPServer(0, self.site)
133- self.server.setServiceParent(self.service_collection)
134- if self.ssl_server:
135- self.ssl_server.setServiceParent(self.service_collection)
136- self.service_collection.startService()
137-
138- def get_root_resource(self):
139- """Get the root resource with all the children."""
140- raise NotImplementedError
141-
142- def get_iri(self):
143- """Build the iri for this mock server."""
144- url = u"http://127.0.0.1:%d/"
145- return url % self.get_port()
146-
147- def get_ssl_iri(self):
148- """Build the ssl iri for this mock server."""
149- if self.ssl_server:
150- url = u"https://127.0.0.1:%d/"
151- return url % self.get_ssl_port()
152-
153- def get_port(self):
154- """Return the port where we are listening."""
155- # pylint: disable=W0212
156- return self.server._port.getHost().port
157- # pylint: enable=W0212
158-
159- def get_ssl_port(self):
160- """Return the ssl port where we are listening."""
161- # pylint: disable=W0212
162- if self.ssl_server:
163- return self.ssl_server._port.getHost().port
164- # pylint: enable=W0212
165-
166- def stop(self):
167- """Shut it down."""
168- #pylint: disable=E1101
169- if self.site.protocol.protocolInstance:
170- self.site.protocol.protocolInstance.timeoutConnection()
171- return self.service_collection.stopService()
172
173=== modified file 'ubuntu_sso/utils/webclient/tests/test_timestamp.py'
174--- ubuntu_sso/utils/webclient/tests/test_timestamp.py 2012-04-09 17:38:24 +0000
175+++ ubuntu_sso/utils/webclient/tests/test_timestamp.py 2012-04-17 20:34:24 +0000
176@@ -32,8 +32,9 @@
177 from twisted.trial.unittest import TestCase
178 from twisted.web import resource
179
180+from ubuntuone.devtools.testing.txwebserver import HTTPWebServer
181+
182 from ubuntu_sso.utils.webclient import timestamp, webclient_module
183-from ubuntu_sso.utils.webclient.tests import BaseMockWebServer
184
185
186 class FakedError(Exception):
187@@ -59,12 +60,12 @@
188 return ""
189
190
191-class MockWebServer(BaseMockWebServer):
192+class MockWebServer(HTTPWebServer):
193 """A mock webserver for testing."""
194
195- def get_root_resource(self):
196- """Get the root resource with all the children."""
197- return RootResource()
198+ def __init__(self):
199+ """Create a new server."""
200+ super(MockWebServer, self).__init__(RootResource())
201
202
203 class TimestampCheckerTestCase(TestCase):
204@@ -76,6 +77,7 @@
205 def setUp(self):
206 yield super(TimestampCheckerTestCase, self).setUp()
207 self.ws = MockWebServer()
208+ self.ws.start()
209 self.addCleanup(self.ws.stop)
210 self.webclient_class = webclient_module().WebClient
211 self.patch(timestamp.TimestampChecker, "SERVER_IRI", self.ws.get_iri())
212
213=== modified file 'ubuntu_sso/utils/webclient/tests/test_webclient.py'
214--- ubuntu_sso/utils/webclient/tests/test_webclient.py 2012-04-12 12:07:46 +0000
215+++ ubuntu_sso/utils/webclient/tests/test_webclient.py 2012-04-17 20:34:24 +0000
216@@ -42,6 +42,11 @@
217
218 from ubuntuone.devtools.testcases import TestCase
219 from ubuntuone.devtools.testcases.squid import SquidTestCase
220+from ubuntuone.devtools.testing.txwebserver import (
221+ HTTPWebServer,
222+ HTTPSWebServer,
223+)
224+
225
226 from ubuntu_sso import (
227 keyring,
228@@ -53,7 +58,6 @@
229 from ubuntu_sso.utils.ui import SSL_DETAILS_TEMPLATE
230 from ubuntu_sso.utils.webclient import gsettings, txweb
231 from ubuntu_sso.utils.webclient.common import BaseWebClient, HeaderDict, oauth
232-from ubuntu_sso.utils.webclient.tests import BaseMockWebServer
233
234 ANY_VALUE = object()
235 SAMPLE_KEY = "result"
236@@ -182,34 +186,49 @@
237 return "ERROR: Expected OAuth header not present."
238
239
240-class MockWebServer(BaseMockWebServer):
241- """A mock webserver for the webclient tests."""
242-
243- def get_root_resource(self):
244- """Get the root resource with all the children."""
245- root = resource.Resource()
246- root.putChild(SIMPLERESOURCE, SimpleResource())
247- root.putChild(BYTEZERORESOURCE, ByteZeroResource())
248- root.putChild(POSTABLERESOURCE, PostableResource())
249-
250- root.putChild(THROWERROR, resource.NoResource())
251-
252- unauthorized_resource = resource.ErrorPage(resource.http.UNAUTHORIZED,
253+def get_root_resource():
254+ """Get the root resource with all the children."""
255+ root = resource.Resource()
256+ root.putChild(SIMPLERESOURCE, SimpleResource())
257+ root.putChild(BYTEZERORESOURCE, ByteZeroResource())
258+ root.putChild(POSTABLERESOURCE, PostableResource())
259+
260+ root.putChild(THROWERROR, resource.NoResource())
261+
262+ unauthorized_resource = resource.ErrorPage(resource.http.UNAUTHORIZED,
263 "Unauthorized", "Unauthorized")
264- root.putChild(UNAUTHORIZED, unauthorized_resource)
265- root.putChild(HEADONLY, HeadOnlyResource())
266- root.putChild(VERIFYHEADERS, VerifyHeadersResource())
267- root.putChild(VERIFYPOSTPARAMS, VerifyPostParameters())
268- root.putChild(OAUTHRESOURCE, OAuthCheckerResource())
269+ root.putChild(UNAUTHORIZED, unauthorized_resource)
270+ root.putChild(HEADONLY, HeadOnlyResource())
271+ root.putChild(VERIFYHEADERS, VerifyHeadersResource())
272+ root.putChild(VERIFYPOSTPARAMS, VerifyPostParameters())
273+ root.putChild(OAUTHRESOURCE, OAuthCheckerResource())
274
275- db = checkers.InMemoryUsernamePasswordDatabaseDontUse()
276- db.addUser(SAMPLE_USERNAME, SAMPLE_PASSWORD)
277- test_portal = portal.Portal(SimpleRealm(), [db])
278- cred_factory = guard.BasicCredentialFactory("example.org")
279- guarded_resource = guard.HTTPAuthSessionWrapper(test_portal,
280+ db = checkers.InMemoryUsernamePasswordDatabaseDontUse()
281+ db.addUser(SAMPLE_USERNAME, SAMPLE_PASSWORD)
282+ test_portal = portal.Portal(SimpleRealm(), [db])
283+ cred_factory = guard.BasicCredentialFactory("example.org")
284+ guarded_resource = guard.HTTPAuthSessionWrapper(test_portal,
285 [cred_factory])
286- root.putChild(GUARDED, guarded_resource)
287- return root
288+ root.putChild(GUARDED, guarded_resource)
289+ return root
290+
291+
292+class HTTPMockWebServer(HTTPWebServer):
293+ """A mock webserver for the webclient tests."""
294+
295+ def __init__(self):
296+ """Create a new instance."""
297+ root = get_root_resource()
298+ super(HTTPMockWebServer, self).__init__(root)
299+
300+
301+class HTTPSMockWebServer(HTTPSWebServer):
302+ """A mock webserver for the webclient tests."""
303+
304+ def __init__(self, ssl_settings):
305+ """Create a new instance."""
306+ root = get_root_resource()
307+ super(HTTPSMockWebServer, self).__init__(root, ssl_settings)
308
309
310 class FakeQApplication(object):
311@@ -264,11 +283,12 @@
312 @defer.inlineCallbacks
313 def setUp(self):
314 yield super(WebClientTestCase, self).setUp()
315- self.ws = MockWebServer()
316- self.addCleanup(self.ws.stop)
317- self.base_iri = self.ws.get_iri()
318 self.wc = self.webclient_factory()
319 self.addCleanup(self.wc.shutdown)
320+ self.ws = HTTPMockWebServer()
321+ self.ws.start()
322+ self.addCleanup(self.ws.stop)
323+ self.base_iri = self.ws.get_iri()
324
325 @defer.inlineCallbacks
326 def test_request_takes_an_iri(self):
327@@ -420,6 +440,52 @@
328
329 webclient_factory = txweb.WebClient
330
331+ @defer.inlineCallbacks
332+ def setUp(self):
333+ """Set the diff tests."""
334+ # delay import, otherwise a default reactor gets installed
335+ from twisted.web import client
336+ self.factory = client.HTTPClientFactory
337+ # set the factory to be used
338+ # Hook the server's buildProtocol to make the protocol instance
339+ # accessible to tests and ensure that the reactor is clean!
340+ build_protocol = self.factory.buildProtocol
341+ self.serverProtocol = None
342+
343+ def remember_protocol_instance(my_self, addr):
344+ """Remember the protocol used in the test."""
345+ protocol = build_protocol(my_self, addr)
346+ self.serverProtocol = protocol
347+ on_connection_lost = defer.Deferred()
348+ connection_lost = protocol.connectionLost
349+
350+ def defer_connection_lost(protocol, *a):
351+ """Lost connection."""
352+ if not on_connection_lost.called:
353+ on_connection_lost.callback(None)
354+ connection_lost(protocol, *a)
355+
356+ self.patch(protocol, 'connectionLost', defer_connection_lost)
357+
358+ def cleanup():
359+ """Clean the connection."""
360+ if self.serverProtocol.transport is not None:
361+ self.serverProtocol.transport.loseConnection()
362+ return on_connection_lost
363+
364+ self.addCleanup(cleanup)
365+ return protocol
366+
367+ self.factory.buildProtocol = remember_protocol_instance
368+ self.addCleanup(self.set_build_protocol, build_protocol)
369+ txweb.WebClient.client_factory = self.factory
370+
371+ yield super(TxWebClientTestCase, self).setUp()
372+
373+ def set_build_protocol(self, method):
374+ """Set the method back."""
375+ self.factory.buildProtocol = method
376+
377
378 class TxWebClientReactorReplaceableTestCase(TestCase):
379 """In the txweb client the reactor is replaceable."""
380@@ -478,7 +544,8 @@
381 @defer.inlineCallbacks
382 def setUp(self):
383 yield super(BasicProxyTestCase, self).setUp()
384- self.ws = MockWebServer()
385+ self.ws = HTTPMockWebServer()
386+ self.ws.start()
387 self.addCleanup(self.ws.stop)
388 self.base_iri = self.ws.get_iri()
389 self.wc = webclient.webclient_factory()
390@@ -891,10 +958,10 @@
391 self.cert_details)
392 self.addCleanup(self._clean_ssl_certificate_files)
393
394- self.ws = MockWebServer(self.ssl_settings)
395+ self.ws = HTTPSMockWebServer(self.ssl_settings)
396+ self.ws.start()
397 self.addCleanup(self.ws.stop)
398 self.base_iri = self.ws.get_iri()
399- self.base_ssl_iri = self.ws.get_ssl_iri()
400
401 def _clean_ssl_certificate_files(self):
402 """Remove the certificate files."""
403@@ -995,7 +1062,7 @@
404 """
405 # we fail due to the fake ssl cert
406 yield self.failUnlessFailure(self.wc.request(
407- self.base_ssl_iri + SIMPLERESOURCE),
408+ self.base_iri + SIMPLERESOURCE),
409 webclient.WebClientError)
410 # https requests do not use the auth proxy therefore called should be
411 # empty. This asserts that we are using the correct settings for the
412@@ -1062,7 +1129,7 @@
413 self.return_code = USER_SUCCESS
414 if proxy_settings:
415 self.wc.force_use_proxy(proxy_settings)
416- yield self.wc.request(self.base_ssl_iri + SIMPLERESOURCE)
417+ yield self.wc.request(self.base_iri + SIMPLERESOURCE)
418 details = SSL_DETAILS_TEMPLATE % self.cert_details
419 self.assertIn(('_launch_ssl_dialog', gethostname(), details),
420 self.called)

Subscribers

People subscribed via source and target branches