Merge lp:~gz/pyjuju/0.5_unicode_token_backport into lp:pyjuju/0.5

Proposed by Martin Packman
Status: Merged
Merged at revision: 559
Proposed branch: lp:~gz/pyjuju/0.5_unicode_token_backport
Merge into: lp:pyjuju/0.5
Diff against target: 126 lines (+72/-9)
2 files modified
juju/providers/openstack/client.py (+6/-3)
juju/providers/openstack/tests/test_client.py (+66/-6)
To merge this branch: bzr merge lp:~gz/pyjuju/0.5_unicode_token_backport
Reviewer Review Type Date Requested Status
John A Meinel Approve
Martin Packman (community) Approve
Review via email: mp+156610@code.launchpad.net

Description of the change

Backport simple but niche issue with token encoding

See the original merge proposal for more details:

<https://code.launchpad.net/~gz/juju/os_token_string_type_1030897/+merge/127008>

To post a comment you must log in.
Revision history for this message
Martin Packman (gz) wrote :

Test suite passes with change.

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'juju/providers/openstack/client.py'
--- juju/providers/openstack/client.py 2012-09-27 19:07:21 +0000
+++ juju/providers/openstack/client.py 2013-04-02 15:20:32 +0000
@@ -33,9 +33,9 @@
33from twisted.web.client import Agent33from twisted.web.client import Agent
34# Older twisted versions don't expose _newclient exceptions via client module34# Older twisted versions don't expose _newclient exceptions via client module
35try:35try:
36 from twisted.web.client import ResponseFailed36 from twisted.web.client import ResponseDone, ResponseFailed
37except ImportError:37except ImportError:
38 from twisted.web._newclient import ResponseFailed38 from twisted.web._newclient import ResponseDone, ResponseFailed
39from twisted.web.http_headers import Headers39from twisted.web.http_headers import Headers
40from zope.interface import implements40from zope.interface import implements
4141
@@ -249,7 +249,10 @@
249 def _handle_v2_auth(self, result):249 def _handle_v2_auth(self, result):
250 access_details = self._json(result, 200, 'access')250 access_details = self._json(result, 200, 'access')
251 token_details = access_details["token"]251 token_details = access_details["token"]
252 self.token = token_details["id"]252 # Decoded json uses unicode for all string values, but that can upset
253 # twisted when serialising headers later. Really should encode at that
254 # point, but as keystone should only give ascii tokens a cast will do.
255 self.token = token_details["id"].encode("ascii")
253256
254 # TODO: care about token_details["expires"]257 # TODO: care about token_details["expires"]
255 # Don't need to we're not preserving tokens.258 # Don't need to we're not preserving tokens.
256259
=== modified file 'juju/providers/openstack/tests/test_client.py'
--- juju/providers/openstack/tests/test_client.py 2012-09-27 19:07:21 +0000
+++ juju/providers/openstack/tests/test_client.py 2013-04-02 15:20:32 +0000
@@ -62,10 +62,19 @@
62class FakeResponse(object):62class FakeResponse(object):
63 """Bare minimum needed to look like a twisted http response"""63 """Bare minimum needed to look like a twisted http response"""
6464
65 def __init__(self, code, headers):65 def __init__(self, code, headers, body=None):
66 self.code = code66 self.code = code
67 self.headers = headers67 self.headers = headers
68 self.length = 068 if body is None:
69 self.length = 0
70 else:
71 self.length = len(body)
72 self.body = body
73
74 def deliverBody(self, reader):
75 reader.connectionMade()
76 reader.dataReceived(self.body)
77 reader.connectionLost(client.ResponseDone())
6978
7079
71class ClientTests(testing.TestCase):80class ClientTests(testing.TestCase):
@@ -106,6 +115,18 @@
106 self.mocker.result(self.mock_agent)115 self.mocker.result(self.mock_agent)
107 return config, osc116 return config, osc
108117
118 def make_client_userpass(self):
119 config = {
120 "auth-url": "https://testing.invalid/v2.0/",
121 "username": "user",
122 "password": "pass",
123 "project-name": "project",
124 }
125 osc = client._OpenStackClient(self.get_credentials(config), True)
126 self.mock_agent(reactor, contextFactory=mocker.MATCH(self.is_checker))
127 self.mocker.result(self.mock_agent)
128 return config, osc
129
109 @defer.inlineCallbacks130 @defer.inlineCallbacks
110 def test_auth_legacy(self):131 def test_auth_legacy(self):
111 config, osc = self.make_client_legacy()132 config, osc = self.make_client_legacy()
@@ -119,10 +140,49 @@
119 self.mocker.replay()140 self.mocker.replay()
120 log = self.capture_logging()141 log = self.capture_logging()
121 yield osc.authenticate()142 yield osc.authenticate()
122 self.assertEqual("tok", osc.token)143 self.assertIsInstance(osc.token, str)
123 self.assertEqual("http://testing.invalid/compute/path",144 self.assertEqual("tok", osc.token)
124 osc._make_url("compute", ["path"]))145 self.assertEqual("http://testing.invalid/compute/path",
125 self.assertIn("compute service not using secure", log.getvalue())146 osc._make_url("compute", ["path"]))
147 self.assertIn("compute service not using secure", log.getvalue())
148
149 @defer.inlineCallbacks
150 def test_auth_userpass(self):
151 config, osc = self.make_client_userpass()
152 self.mock_agent.request("POST", "https://testing.invalid/v2.0/tokens",
153 mocker.ANY, mocker.ANY)
154 response = FakeResponse(200, http_headers.Headers({
155 "Content-Type": ["application/json"],
156 }),
157 json.dumps({'access': {
158 'token': {'id': "tok", 'expires': "shortly"},
159 'serviceCatalog': [
160 {
161 'type': "compute",
162 'endpoints': [
163 {'publicURL': "http://testing.invalid/compute"},
164 ],
165 },
166 {
167 'type': "object-store",
168 'endpoints': [
169 {'publicURL': "http://testing.invalid/objstore"},
170 ],
171 },
172 ],
173 }}))
174 self.mocker.result(defer.succeed(response))
175 self.mocker.replay()
176 log = self.capture_logging()
177 yield osc.authenticate()
178 self.assertIsInstance(osc.token, str)
179 self.assertEqual("tok", osc.token)
180 self.assertEqual("http://testing.invalid/compute/path",
181 osc._make_url("compute", ["path"]))
182 self.assertEqual("http://testing.invalid/objstore/path",
183 osc._make_url("object-store", ["path"]))
184 self.assertIn("compute service not using secure", log.getvalue())
185 self.assertIn("object-store service not using secure", log.getvalue())
126186
127 def test_cert_failure(self):187 def test_cert_failure(self):
128 config, osc = self.make_client_legacy()188 config, osc = self.make_client_legacy()

Subscribers

People subscribed via source and target branches