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
=== modified file 'ubuntu_sso/utils/tests/test_common.py'
--- ubuntu_sso/utils/tests/test_common.py 2012-04-09 17:38:24 +0000
+++ ubuntu_sso/utils/tests/test_common.py 2012-04-17 20:34:24 +0000
@@ -33,11 +33,11 @@
33import sys33import sys
34import time34import time
3535
36from twisted.application import internet, service
37from twisted.internet import defer36from twisted.internet import defer
38from twisted.internet.threads import deferToThread37from twisted.internet.threads import deferToThread
39from twisted.web import server, resource38from twisted.web import resource
40from ubuntuone.devtools.handlers import MementoHandler39from ubuntuone.devtools.handlers import MementoHandler
40from ubuntuone.devtools.testing.txwebserver import HTTPWebServer
4141
42from ubuntu_sso import utils42from ubuntu_sso import utils
43from ubuntu_sso.tests import TestCase, EMAIL, TOKEN43from ubuntu_sso.tests import TestCase, EMAIL, TOKEN
@@ -306,30 +306,14 @@
306 return ""306 return ""
307307
308308
309class MockWebServer(object):309class MockWebServer(HTTPWebServer):
310 """A mock webserver for testing."""310 """A mock webserver for testing."""
311311
312 def __init__(self):312 def __init__(self):
313 """Start up this instance."""313 """Start up this instance."""
314 # pylint: disable=E1101314 # pylint: disable=E1101
315 self.root = RootResource()315 root = RootResource()
316 site = server.Site(self.root)316 super(MockWebServer, self).__init__(root)
317 application = service.Application('web')
318 self.service_collection = service.IServiceCollection(application)
319 self.tcpserver = internet.TCPServer(0, site)
320 self.tcpserver.setServiceParent(self.service_collection)
321 self.service_collection.startService()
322
323 def get_url(self):
324 """Build the url for this mock server."""
325 # pylint: disable=W0212
326 port_num = self.tcpserver._port.getHost().port
327 return "http://localhost:%d/" % port_num
328
329 def stop(self):
330 """Shut it down."""
331 # pylint: disable=E1101
332 self.service_collection.stopService()
333317
334318
335class FakedError(Exception):319class FakedError(Exception):
@@ -344,8 +328,9 @@
344 """Initialize a fake webserver."""328 """Initialize a fake webserver."""
345 yield super(TimestampCheckerTestCase, self).setUp()329 yield super(TimestampCheckerTestCase, self).setUp()
346 self.ws = MockWebServer()330 self.ws = MockWebServer()
331 self.ws.start()
347 self.addCleanup(self.ws.stop)332 self.addCleanup(self.ws.stop)
348 self.patch(SyncTimestampChecker, "SERVER_URL", self.ws.get_url())333 self.patch(SyncTimestampChecker, "SERVER_URL", self.ws.get_iri())
349334
350 @defer.inlineCallbacks335 @defer.inlineCallbacks
351 def test_returned_value_is_int(self):336 def test_returned_value_is_int(self):
352337
=== modified file 'ubuntu_sso/utils/webclient/tests/__init__.py'
--- ubuntu_sso/utils/webclient/tests/__init__.py 2012-04-09 17:38:24 +0000
+++ ubuntu_sso/utils/webclient/tests/__init__.py 2012-04-17 20:34:24 +0000
@@ -28,14 +28,6 @@
28# files in the program, then also delete it here.28# files in the program, then also delete it here.
29"""Tests for the proxy-aware webclient."""29"""Tests for the proxy-aware webclient."""
3030
31from twisted.application import internet, service
32from twisted.internet import ssl
33from twisted.web import http, server
34
35
36# Some settings are not used as described in:
37# https://bugzilla.gnome.org/show_bug.cgi?id=648237
38
39TEMPLATE_GSETTINGS_OUTPUT = """\31TEMPLATE_GSETTINGS_OUTPUT = """\
40org.gnome.system.proxy autoconfig-url '{autoconfig_url}'32org.gnome.system.proxy autoconfig-url '{autoconfig_url}'
41org.gnome.system.proxy ignore-hosts {ignore_hosts:s}33org.gnome.system.proxy ignore-hosts {ignore_hosts:s}
@@ -69,89 +61,3 @@
69 "socks_host": "",61 "socks_host": "",
70 "socks_port": 0,62 "socks_port": 0,
71}63}
72
73
74class SaveHTTPChannel(http.HTTPChannel):
75 """A save protocol to be used in tests."""
76
77 protocolInstance = None
78
79 # pylint: disable=C0103
80 def connectionMade(self):
81 """Keep track of the given protocol."""
82 SaveHTTPChannel.protocolInstance = self
83 http.HTTPChannel.connectionMade(self)
84
85
86class SaveSite(server.Site):
87 """A site that let us know when it closed."""
88
89 protocol = SaveHTTPChannel
90
91 def __init__(self, *args, **kwargs):
92 """Create a new instance."""
93 server.Site.__init__(self, *args, **kwargs)
94 # we disable the timeout in the tests, we will deal with it manually.
95 # pylint: disable=C0103
96 self.timeOut = None
97
98
99class BaseMockWebServer(object):
100 """A mock webserver for testing"""
101
102 def __init__(self, ssl_settings=None):
103 """Start up this instance."""
104 self.root = self.get_root_resource()
105 self.site = SaveSite(self.root)
106 application = service.Application('web')
107 self.service_collection = service.IServiceCollection(application)
108 #pylint: disable=E1101
109 ssl_context = None
110 if (ssl_settings is not None
111 and 'key' in ssl_settings
112 and 'cert' in ssl_settings):
113 ssl_context = ssl.DefaultOpenSSLContextFactory(ssl_settings['key'],
114 ssl_settings['cert'])
115 self.ssl_server = internet.SSLServer(0, self.site, ssl_context)
116 else:
117 self.ssl_server = None
118 self.server = internet.TCPServer(0, self.site)
119 self.server.setServiceParent(self.service_collection)
120 if self.ssl_server:
121 self.ssl_server.setServiceParent(self.service_collection)
122 self.service_collection.startService()
123
124 def get_root_resource(self):
125 """Get the root resource with all the children."""
126 raise NotImplementedError
127
128 def get_iri(self):
129 """Build the iri for this mock server."""
130 url = u"http://127.0.0.1:%d/"
131 return url % self.get_port()
132
133 def get_ssl_iri(self):
134 """Build the ssl iri for this mock server."""
135 if self.ssl_server:
136 url = u"https://127.0.0.1:%d/"
137 return url % self.get_ssl_port()
138
139 def get_port(self):
140 """Return the port where we are listening."""
141 # pylint: disable=W0212
142 return self.server._port.getHost().port
143 # pylint: enable=W0212
144
145 def get_ssl_port(self):
146 """Return the ssl port where we are listening."""
147 # pylint: disable=W0212
148 if self.ssl_server:
149 return self.ssl_server._port.getHost().port
150 # pylint: enable=W0212
151
152 def stop(self):
153 """Shut it down."""
154 #pylint: disable=E1101
155 if self.site.protocol.protocolInstance:
156 self.site.protocol.protocolInstance.timeoutConnection()
157 return self.service_collection.stopService()
15864
=== modified file 'ubuntu_sso/utils/webclient/tests/test_timestamp.py'
--- ubuntu_sso/utils/webclient/tests/test_timestamp.py 2012-04-09 17:38:24 +0000
+++ ubuntu_sso/utils/webclient/tests/test_timestamp.py 2012-04-17 20:34:24 +0000
@@ -32,8 +32,9 @@
32from twisted.trial.unittest import TestCase32from twisted.trial.unittest import TestCase
33from twisted.web import resource33from twisted.web import resource
3434
35from ubuntuone.devtools.testing.txwebserver import HTTPWebServer
36
35from ubuntu_sso.utils.webclient import timestamp, webclient_module37from ubuntu_sso.utils.webclient import timestamp, webclient_module
36from ubuntu_sso.utils.webclient.tests import BaseMockWebServer
3738
3839
39class FakedError(Exception):40class FakedError(Exception):
@@ -59,12 +60,12 @@
59 return ""60 return ""
6061
6162
62class MockWebServer(BaseMockWebServer):63class MockWebServer(HTTPWebServer):
63 """A mock webserver for testing."""64 """A mock webserver for testing."""
6465
65 def get_root_resource(self):66 def __init__(self):
66 """Get the root resource with all the children."""67 """Create a new server."""
67 return RootResource()68 super(MockWebServer, self).__init__(RootResource())
6869
6970
70class TimestampCheckerTestCase(TestCase):71class TimestampCheckerTestCase(TestCase):
@@ -76,6 +77,7 @@
76 def setUp(self):77 def setUp(self):
77 yield super(TimestampCheckerTestCase, self).setUp()78 yield super(TimestampCheckerTestCase, self).setUp()
78 self.ws = MockWebServer()79 self.ws = MockWebServer()
80 self.ws.start()
79 self.addCleanup(self.ws.stop)81 self.addCleanup(self.ws.stop)
80 self.webclient_class = webclient_module().WebClient82 self.webclient_class = webclient_module().WebClient
81 self.patch(timestamp.TimestampChecker, "SERVER_IRI", self.ws.get_iri())83 self.patch(timestamp.TimestampChecker, "SERVER_IRI", self.ws.get_iri())
8284
=== modified file 'ubuntu_sso/utils/webclient/tests/test_webclient.py'
--- ubuntu_sso/utils/webclient/tests/test_webclient.py 2012-04-12 12:07:46 +0000
+++ ubuntu_sso/utils/webclient/tests/test_webclient.py 2012-04-17 20:34:24 +0000
@@ -42,6 +42,11 @@
4242
43from ubuntuone.devtools.testcases import TestCase43from ubuntuone.devtools.testcases import TestCase
44from ubuntuone.devtools.testcases.squid import SquidTestCase44from ubuntuone.devtools.testcases.squid import SquidTestCase
45from ubuntuone.devtools.testing.txwebserver import (
46 HTTPWebServer,
47 HTTPSWebServer,
48)
49
4550
46from ubuntu_sso import (51from ubuntu_sso import (
47 keyring,52 keyring,
@@ -53,7 +58,6 @@
53from ubuntu_sso.utils.ui import SSL_DETAILS_TEMPLATE58from ubuntu_sso.utils.ui import SSL_DETAILS_TEMPLATE
54from ubuntu_sso.utils.webclient import gsettings, txweb59from ubuntu_sso.utils.webclient import gsettings, txweb
55from ubuntu_sso.utils.webclient.common import BaseWebClient, HeaderDict, oauth60from ubuntu_sso.utils.webclient.common import BaseWebClient, HeaderDict, oauth
56from ubuntu_sso.utils.webclient.tests import BaseMockWebServer
5761
58ANY_VALUE = object()62ANY_VALUE = object()
59SAMPLE_KEY = "result"63SAMPLE_KEY = "result"
@@ -182,34 +186,49 @@
182 return "ERROR: Expected OAuth header not present."186 return "ERROR: Expected OAuth header not present."
183187
184188
185class MockWebServer(BaseMockWebServer):189def get_root_resource():
186 """A mock webserver for the webclient tests."""190 """Get the root resource with all the children."""
187191 root = resource.Resource()
188 def get_root_resource(self):192 root.putChild(SIMPLERESOURCE, SimpleResource())
189 """Get the root resource with all the children."""193 root.putChild(BYTEZERORESOURCE, ByteZeroResource())
190 root = resource.Resource()194 root.putChild(POSTABLERESOURCE, PostableResource())
191 root.putChild(SIMPLERESOURCE, SimpleResource())195
192 root.putChild(BYTEZERORESOURCE, ByteZeroResource())196 root.putChild(THROWERROR, resource.NoResource())
193 root.putChild(POSTABLERESOURCE, PostableResource())197
194198 unauthorized_resource = resource.ErrorPage(resource.http.UNAUTHORIZED,
195 root.putChild(THROWERROR, resource.NoResource())
196
197 unauthorized_resource = resource.ErrorPage(resource.http.UNAUTHORIZED,
198 "Unauthorized", "Unauthorized")199 "Unauthorized", "Unauthorized")
199 root.putChild(UNAUTHORIZED, unauthorized_resource)200 root.putChild(UNAUTHORIZED, unauthorized_resource)
200 root.putChild(HEADONLY, HeadOnlyResource())201 root.putChild(HEADONLY, HeadOnlyResource())
201 root.putChild(VERIFYHEADERS, VerifyHeadersResource())202 root.putChild(VERIFYHEADERS, VerifyHeadersResource())
202 root.putChild(VERIFYPOSTPARAMS, VerifyPostParameters())203 root.putChild(VERIFYPOSTPARAMS, VerifyPostParameters())
203 root.putChild(OAUTHRESOURCE, OAuthCheckerResource())204 root.putChild(OAUTHRESOURCE, OAuthCheckerResource())
204205
205 db = checkers.InMemoryUsernamePasswordDatabaseDontUse()206 db = checkers.InMemoryUsernamePasswordDatabaseDontUse()
206 db.addUser(SAMPLE_USERNAME, SAMPLE_PASSWORD)207 db.addUser(SAMPLE_USERNAME, SAMPLE_PASSWORD)
207 test_portal = portal.Portal(SimpleRealm(), [db])208 test_portal = portal.Portal(SimpleRealm(), [db])
208 cred_factory = guard.BasicCredentialFactory("example.org")209 cred_factory = guard.BasicCredentialFactory("example.org")
209 guarded_resource = guard.HTTPAuthSessionWrapper(test_portal,210 guarded_resource = guard.HTTPAuthSessionWrapper(test_portal,
210 [cred_factory])211 [cred_factory])
211 root.putChild(GUARDED, guarded_resource)212 root.putChild(GUARDED, guarded_resource)
212 return root213 return root
214
215
216class HTTPMockWebServer(HTTPWebServer):
217 """A mock webserver for the webclient tests."""
218
219 def __init__(self):
220 """Create a new instance."""
221 root = get_root_resource()
222 super(HTTPMockWebServer, self).__init__(root)
223
224
225class HTTPSMockWebServer(HTTPSWebServer):
226 """A mock webserver for the webclient tests."""
227
228 def __init__(self, ssl_settings):
229 """Create a new instance."""
230 root = get_root_resource()
231 super(HTTPSMockWebServer, self).__init__(root, ssl_settings)
213232
214233
215class FakeQApplication(object):234class FakeQApplication(object):
@@ -264,11 +283,12 @@
264 @defer.inlineCallbacks283 @defer.inlineCallbacks
265 def setUp(self):284 def setUp(self):
266 yield super(WebClientTestCase, self).setUp()285 yield super(WebClientTestCase, self).setUp()
267 self.ws = MockWebServer()
268 self.addCleanup(self.ws.stop)
269 self.base_iri = self.ws.get_iri()
270 self.wc = self.webclient_factory()286 self.wc = self.webclient_factory()
271 self.addCleanup(self.wc.shutdown)287 self.addCleanup(self.wc.shutdown)
288 self.ws = HTTPMockWebServer()
289 self.ws.start()
290 self.addCleanup(self.ws.stop)
291 self.base_iri = self.ws.get_iri()
272292
273 @defer.inlineCallbacks293 @defer.inlineCallbacks
274 def test_request_takes_an_iri(self):294 def test_request_takes_an_iri(self):
@@ -420,6 +440,52 @@
420440
421 webclient_factory = txweb.WebClient441 webclient_factory = txweb.WebClient
422442
443 @defer.inlineCallbacks
444 def setUp(self):
445 """Set the diff tests."""
446 # delay import, otherwise a default reactor gets installed
447 from twisted.web import client
448 self.factory = client.HTTPClientFactory
449 # set the factory to be used
450 # Hook the server's buildProtocol to make the protocol instance
451 # accessible to tests and ensure that the reactor is clean!
452 build_protocol = self.factory.buildProtocol
453 self.serverProtocol = None
454
455 def remember_protocol_instance(my_self, addr):
456 """Remember the protocol used in the test."""
457 protocol = build_protocol(my_self, addr)
458 self.serverProtocol = protocol
459 on_connection_lost = defer.Deferred()
460 connection_lost = protocol.connectionLost
461
462 def defer_connection_lost(protocol, *a):
463 """Lost connection."""
464 if not on_connection_lost.called:
465 on_connection_lost.callback(None)
466 connection_lost(protocol, *a)
467
468 self.patch(protocol, 'connectionLost', defer_connection_lost)
469
470 def cleanup():
471 """Clean the connection."""
472 if self.serverProtocol.transport is not None:
473 self.serverProtocol.transport.loseConnection()
474 return on_connection_lost
475
476 self.addCleanup(cleanup)
477 return protocol
478
479 self.factory.buildProtocol = remember_protocol_instance
480 self.addCleanup(self.set_build_protocol, build_protocol)
481 txweb.WebClient.client_factory = self.factory
482
483 yield super(TxWebClientTestCase, self).setUp()
484
485 def set_build_protocol(self, method):
486 """Set the method back."""
487 self.factory.buildProtocol = method
488
423489
424class TxWebClientReactorReplaceableTestCase(TestCase):490class TxWebClientReactorReplaceableTestCase(TestCase):
425 """In the txweb client the reactor is replaceable."""491 """In the txweb client the reactor is replaceable."""
@@ -478,7 +544,8 @@
478 @defer.inlineCallbacks544 @defer.inlineCallbacks
479 def setUp(self):545 def setUp(self):
480 yield super(BasicProxyTestCase, self).setUp()546 yield super(BasicProxyTestCase, self).setUp()
481 self.ws = MockWebServer()547 self.ws = HTTPMockWebServer()
548 self.ws.start()
482 self.addCleanup(self.ws.stop)549 self.addCleanup(self.ws.stop)
483 self.base_iri = self.ws.get_iri()550 self.base_iri = self.ws.get_iri()
484 self.wc = webclient.webclient_factory()551 self.wc = webclient.webclient_factory()
@@ -891,10 +958,10 @@
891 self.cert_details)958 self.cert_details)
892 self.addCleanup(self._clean_ssl_certificate_files)959 self.addCleanup(self._clean_ssl_certificate_files)
893960
894 self.ws = MockWebServer(self.ssl_settings)961 self.ws = HTTPSMockWebServer(self.ssl_settings)
962 self.ws.start()
895 self.addCleanup(self.ws.stop)963 self.addCleanup(self.ws.stop)
896 self.base_iri = self.ws.get_iri()964 self.base_iri = self.ws.get_iri()
897 self.base_ssl_iri = self.ws.get_ssl_iri()
898965
899 def _clean_ssl_certificate_files(self):966 def _clean_ssl_certificate_files(self):
900 """Remove the certificate files."""967 """Remove the certificate files."""
@@ -995,7 +1062,7 @@
995 """1062 """
996 # we fail due to the fake ssl cert1063 # we fail due to the fake ssl cert
997 yield self.failUnlessFailure(self.wc.request(1064 yield self.failUnlessFailure(self.wc.request(
998 self.base_ssl_iri + SIMPLERESOURCE),1065 self.base_iri + SIMPLERESOURCE),
999 webclient.WebClientError)1066 webclient.WebClientError)
1000 # https requests do not use the auth proxy therefore called should be1067 # https requests do not use the auth proxy therefore called should be
1001 # empty. This asserts that we are using the correct settings for the1068 # empty. This asserts that we are using the correct settings for the
@@ -1062,7 +1129,7 @@
1062 self.return_code = USER_SUCCESS1129 self.return_code = USER_SUCCESS
1063 if proxy_settings:1130 if proxy_settings:
1064 self.wc.force_use_proxy(proxy_settings)1131 self.wc.force_use_proxy(proxy_settings)
1065 yield self.wc.request(self.base_ssl_iri + SIMPLERESOURCE)1132 yield self.wc.request(self.base_iri + SIMPLERESOURCE)
1066 details = SSL_DETAILS_TEMPLATE % self.cert_details1133 details = SSL_DETAILS_TEMPLATE % self.cert_details
1067 self.assertIn(('_launch_ssl_dialog', gethostname(), details),1134 self.assertIn(('_launch_ssl_dialog', gethostname(), details),
1068 self.called)1135 self.called)

Subscribers

People subscribed via source and target branches