Merge lp:~bcwaldon/nova/osapi-versions-links into lp:~hudson-openstack/nova/trunk

Proposed by Brian Waldon
Status: Merged
Approved by: Paul Voccio
Approved revision: 814
Merged at revision: 890
Proposed branch: lp:~bcwaldon/nova/osapi-versions-links
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 281 lines (+213/-20)
6 files modified
etc/api-paste.ini (+1/-1)
nova/api/openstack/__init__.py (+0/-18)
nova/api/openstack/versions.py (+54/-0)
nova/api/openstack/views/versions.py (+59/-0)
nova/tests/api/openstack/fakes.py (+2/-1)
nova/tests/api/openstack/test_versions.py (+97/-0)
To merge this branch: bzr merge lp:~bcwaldon/nova/osapi-versions-links
Reviewer Review Type Date Requested Status
Paul Voccio (community) Approve
Rick Clark (community) Approve
Mark Washenberger (community) Approve
Matt Dietz (community) Approve
Review via email: mp+54265@code.launchpad.net

This proposal supersedes a proposal from 2011-03-17.

Commit message

- add a "links" container to versions entities for Openstack API v1.1
- add testing for the openstack api versions resource and create a view builder

Description of the change

- add a "links" container to versions entities for Openstack API v1.1
- add testing for the openstack api versions resource and create a view builder
- Resubmitted without prerequisite.

To post a comment you must log in.
Revision history for this message
Mark Washenberger (markwash) wrote : Posted in a previous version of this proposal

LGTM -

but I'd like to see some ViewBuilder unit tests in the future.

review: Approve
Revision history for this message
Matt Dietz (cerberus) wrote :

Looks like you've got some conflicts in fakes.py

166 +<<<<<<< TREE
167 from nova.api.openstack import limits
168 +=======
169 +from nova.api.openstack import ratelimiting
170 +from nova.api.openstack import versions
171 +>>>>>>> MERGE-SOURCE

43 +# Copyright 2010 United States Government as represented by the
44 +# Administrator of the National Aeronautics and Space Administration.

Shouldn't this be the Openstack copyright, and be 2011?

Like Mark said, a few unit tests for ViewBuilder wouldn't hurt.

191) Same deal. Shouldn't it be 2011?

I'd check out the pep8 result too. There was a whitespace complaint in test_versions

review: Needs Fixing
Revision history for this message
Brian Waldon (bcwaldon) wrote :

> Looks like you've got some conflicts in fakes.py
>
> 166 +<<<<<<< TREE
> 167 from nova.api.openstack import limits
> 168 +=======
> 169 +from nova.api.openstack import ratelimiting
> 170 +from nova.api.openstack import versions
> 171 +>>>>>>> MERGE-SOURCE
>
>
> 43 +# Copyright 2010 United States Government as represented by the
> 44 +# Administrator of the National Aeronautics and Space Administration.
>
> Shouldn't this be the Openstack copyright, and be 2011?
>
> Like Mark said, a few unit tests for ViewBuilder wouldn't hurt.
>
> 191) Same deal. Shouldn't it be 2011?
>
> I'd check out the pep8 result too. There was a whitespace complaint in
> test_versions

Fixed!

Revision history for this message
Matt Dietz (cerberus) wrote :

I still see the NASA copyright on that file... is this intentional?

review: Needs Fixing
Revision history for this message
Brian Waldon (bcwaldon) wrote :

> I still see the NASA copyright on that file... is this intentional?

Oh, I'm sorry. I just saw "Shouldn't this be the Openstack copyright, and be 2011?" and changed it to 2011. I guess I read too fast. Should be good to go now.

Revision history for this message
Matt Dietz (cerberus) wrote :

187 +# Copyright 2010 OpenStack LLC.

Missed the other, too ;-) Should be 2010 - 2011

Otherwise lgtm. Just fix that last little nit

Revision history for this message
Matt Dietz (cerberus) wrote :

\o/

review: Approve
Revision history for this message
Mark Washenberger (markwash) wrote :

Even better than before.

review: Approve
Revision history for this message
Rick Clark (dendrobates) wrote :

lgtm

review: Approve
Revision history for this message
OpenStack Infra (hudson-openstack) wrote :

Attempt to merge into lp:nova failed due to conflicts:

text conflict in nova/api/openstack/__init__.py

814. By Brian Waldon

merging trunk, resolving conflicts

Revision history for this message
Paul Voccio (pvo) wrote :

merged cleanly, tests passed. lgtm.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'etc/api-paste.ini'
2--- etc/api-paste.ini 2011-03-24 22:47:36 +0000
3+++ etc/api-paste.ini 2011-03-25 14:37:25 +0000
4@@ -98,4 +98,4 @@
5 pipeline = faultwrap osversionapp
6
7 [app:osversionapp]
8-paste.app_factory = nova.api.openstack:Versions.factory
9+paste.app_factory = nova.api.openstack.versions:Versions.factory
10
11=== modified file 'nova/api/openstack/__init__.py'
12--- nova/api/openstack/__init__.py 2011-03-25 14:21:03 +0000
13+++ nova/api/openstack/__init__.py 2011-03-25 14:37:25 +0000
14@@ -158,21 +158,3 @@
15 mapper.resource("flavor", "flavors",
16 controller=flavors.ControllerV11(),
17 collection={'detail': 'GET'})
18-
19-
20-class Versions(wsgi.Application):
21- @webob.dec.wsgify(RequestClass=wsgi.Request)
22- def __call__(self, req):
23- """Respond to a request for all OpenStack API versions."""
24- response = {
25- "versions": [
26- dict(status="DEPRECATED", id="v1.0"),
27- dict(status="CURRENT", id="v1.1"),
28- ],
29- }
30- metadata = {
31- "application/xml": {
32- "attributes": dict(version=["status", "id"])}}
33-
34- content_type = req.best_match_content_type()
35- return wsgi.Serializer(metadata).serialize(response, content_type)
36
37=== added file 'nova/api/openstack/versions.py'
38--- nova/api/openstack/versions.py 1970-01-01 00:00:00 +0000
39+++ nova/api/openstack/versions.py 2011-03-25 14:37:25 +0000
40@@ -0,0 +1,54 @@
41+# vim: tabstop=4 shiftwidth=4 softtabstop=4
42+
43+# Copyright 2011 OpenStack LLC.
44+# All Rights Reserved.
45+#
46+# Licensed under the Apache License, Version 2.0 (the "License"); you may
47+# not use this file except in compliance with the License. You may obtain
48+# a copy of the License at
49+#
50+# http://www.apache.org/licenses/LICENSE-2.0
51+#
52+# Unless required by applicable law or agreed to in writing, software
53+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
54+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
55+# License for the specific language governing permissions and limitations
56+# under the License.
57+
58+import webob.dec
59+import webob.exc
60+
61+from nova import wsgi
62+import nova.api.openstack.views.versions
63+
64+
65+class Versions(wsgi.Application):
66+ @webob.dec.wsgify(RequestClass=wsgi.Request)
67+ def __call__(self, req):
68+ """Respond to a request for all OpenStack API versions."""
69+ version_objs = [
70+ {
71+ "id": "v1.1",
72+ "status": "CURRENT",
73+ },
74+ {
75+ "id": "v1.0",
76+ "status": "DEPRECATED",
77+ },
78+ ]
79+
80+ builder = nova.api.openstack.views.versions.get_view_builder(req)
81+ versions = [builder.build(version) for version in version_objs]
82+ response = dict(versions=versions)
83+
84+ metadata = {
85+ "application/xml": {
86+ "attributes": {
87+ "version": ["status", "id"],
88+ "link": ["rel", "href"],
89+ }
90+ }
91+ }
92+
93+ content_type = req.best_match_content_type()
94+ return wsgi.Serializer(metadata).serialize(response, content_type)
95
96=== added file 'nova/api/openstack/views/versions.py'
97--- nova/api/openstack/views/versions.py 1970-01-01 00:00:00 +0000
98+++ nova/api/openstack/views/versions.py 2011-03-25 14:37:25 +0000
99@@ -0,0 +1,59 @@
100+# vim: tabstop=4 shiftwidth=4 softtabstop=4
101+
102+# Copyright 2010-2011 OpenStack LLC.
103+# All Rights Reserved.
104+#
105+# Licensed under the Apache License, Version 2.0 (the "License"); you may
106+# not use this file except in compliance with the License. You may obtain
107+# a copy of the License at
108+#
109+# http://www.apache.org/licenses/LICENSE-2.0
110+#
111+# Unless required by applicable law or agreed to in writing, software
112+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
113+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
114+# License for the specific language governing permissions and limitations
115+# under the License.
116+
117+import os
118+
119+
120+def get_view_builder(req):
121+ base_url = req.application_url
122+ return ViewBuilder(base_url)
123+
124+
125+class ViewBuilder(object):
126+
127+ def __init__(self, base_url):
128+ """
129+ :param base_url: url of the root wsgi application
130+ """
131+ self.base_url = base_url
132+
133+ def build(self, version_data):
134+ """Generic method used to generate a version entity."""
135+ version = {
136+ "id": version_data["id"],
137+ "status": version_data["status"],
138+ "links": self._build_links(version_data),
139+ }
140+
141+ return version
142+
143+ def _build_links(self, version_data):
144+ """Generate a container of links that refer to the provided version."""
145+ href = self.generate_href(version_data["id"])
146+
147+ links = [
148+ {
149+ "rel": "self",
150+ "href": href,
151+ },
152+ ]
153+
154+ return links
155+
156+ def generate_href(self, version_number):
157+ """Create an url that refers to a specific version_number."""
158+ return os.path.join(self.base_url, version_number)
159
160=== modified file 'nova/tests/api/openstack/fakes.py'
161--- nova/tests/api/openstack/fakes.py 2011-03-24 22:47:36 +0000
162+++ nova/tests/api/openstack/fakes.py 2011-03-25 14:37:25 +0000
163@@ -35,6 +35,7 @@
164 import nova.api.openstack.auth
165 from nova.api import openstack
166 from nova.api.openstack import auth
167+from nova.api.openstack import versions
168 from nova.api.openstack import limits
169 from nova.auth.manager import User, Project
170 from nova.image import glance
171@@ -85,7 +86,7 @@
172 limits.RateLimitingMiddleware(inner_app11)))
173 mapper['/v1.0'] = api10
174 mapper['/v1.1'] = api11
175- mapper['/'] = openstack.FaultWrapper(openstack.Versions())
176+ mapper['/'] = openstack.FaultWrapper(versions.Versions())
177 return mapper
178
179
180
181=== added file 'nova/tests/api/openstack/test_versions.py'
182--- nova/tests/api/openstack/test_versions.py 1970-01-01 00:00:00 +0000
183+++ nova/tests/api/openstack/test_versions.py 2011-03-25 14:37:25 +0000
184@@ -0,0 +1,97 @@
185+# vim: tabstop=4 shiftwidth=4 softtabstop=4
186+
187+# Copyright 2010-2011 OpenStack LLC.
188+# All Rights Reserved.
189+#
190+# Licensed under the Apache License, Version 2.0 (the "License"); you may
191+# not use this file except in compliance with the License. You may obtain
192+# a copy of the License at
193+#
194+# http://www.apache.org/licenses/LICENSE-2.0
195+#
196+# Unless required by applicable law or agreed to in writing, software
197+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
198+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
199+# License for the specific language governing permissions and limitations
200+# under the License.
201+
202+import json
203+import webob
204+
205+from nova import context
206+from nova import test
207+from nova.tests.api.openstack import fakes
208+from nova.api.openstack import views
209+
210+
211+class VersionsTest(test.TestCase):
212+ def setUp(self):
213+ super(VersionsTest, self).setUp()
214+ self.context = context.get_admin_context()
215+
216+ def tearDown(self):
217+ super(VersionsTest, self).tearDown()
218+
219+ def test_get_version_list(self):
220+ req = webob.Request.blank('/')
221+ res = req.get_response(fakes.wsgi_app())
222+ self.assertEqual(res.status_int, 200)
223+ versions = json.loads(res.body)["versions"]
224+ expected = [
225+ {
226+ "id": "v1.1",
227+ "status": "CURRENT",
228+ "links": [
229+ {
230+ "rel": "self",
231+ "href": "http://localhost/v1.1",
232+ }
233+ ],
234+ },
235+ {
236+ "id": "v1.0",
237+ "status": "DEPRECATED",
238+ "links": [
239+ {
240+ "rel": "self",
241+ "href": "http://localhost/v1.0",
242+ }
243+ ],
244+ },
245+ ]
246+ self.assertEqual(versions, expected)
247+
248+ def test_view_builder(self):
249+ base_url = "http://example.org/"
250+
251+ version_data = {
252+ "id": "3.2.1",
253+ "status": "CURRENT",
254+ }
255+
256+ expected = {
257+ "id": "3.2.1",
258+ "status": "CURRENT",
259+ "links": [
260+ {
261+ "rel": "self",
262+ "href": "http://example.org/3.2.1",
263+ },
264+ ],
265+ }
266+
267+ builder = views.versions.ViewBuilder(base_url)
268+ output = builder.build(version_data)
269+
270+ self.assertEqual(output, expected)
271+
272+ def test_generate_href(self):
273+ base_url = "http://example.org/app/"
274+ version_number = "v1.4.6"
275+
276+ expected = "http://example.org/app/v1.4.6"
277+
278+ builder = views.versions.ViewBuilder(base_url)
279+ actual = builder.generate_href(version_number)
280+
281+ self.assertEqual(actual, expected)