Merge lp:~rvb/maas/use-reverse into lp:~maas-committers/maas/trunk

Proposed by Raphaël Badin
Status: Merged
Approved by: Raphaël Badin
Approved revision: no longer in the source branch.
Merged at revision: 659
Proposed branch: lp:~rvb/maas/use-reverse
Merge into: lp:~maas-committers/maas/trunk
Prerequisite: lp:~rvb/maas/pxe-off-preseed
Diff against target: 286 lines (+60/-60)
2 files modified
src/maas/urls.py (+1/-1)
src/metadataserver/tests/test_api.py (+59/-59)
To merge this branch: bzr merge lp:~rvb/maas/use-reverse
Reviewer Review Type Date Requested Status
Gavin Panella (community) Approve
Francesco Banconi (community) code* Approve
Review via email: mp+111240@code.launchpad.net

Commit message

Use Django's reverse in src/metadataserver/tests/test_api.py

Description of the change

This branch fixes a problem I spotted when I was working on the pre-req branch.

The metadata application should be hooked up (in src/maas/urls.py) like this:

urlpatterns = patterns('',
    url(r'^', include('maasserver.urls')),
    url(r'^metadata/', include('metadataserver.urls')),
)

Note the trailing slash at the end of '^metadata/'. Otherwise, reverse(...) does not return a correct path.

See https://docs.djangoproject.com/en/dev/topics/http/urls/#naming-url-patterns for details.

I refactored src/metadataserver/tests/test_api.py to use Django's reverse method everywhere. The main benefit is that now we exercise the name=... part in all the urls definitions in src/metadataserver/urls.py (augmented test coverage). Also, note that this whole branch is neutral in terms of added/removed lines.

To post a comment you must log in.
Revision history for this message
Francesco Banconi (frankban) wrote :

Looks good.

review: Approve (code*)
Revision history for this message
Gavin Panella (allenap) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maas/urls.py'
2--- src/maas/urls.py 2012-04-16 10:00:51 +0000
3+++ src/maas/urls.py 2012-06-20 16:33:18 +0000
4@@ -23,7 +23,7 @@
5
6 urlpatterns = patterns('',
7 url(r'^', include('maasserver.urls')),
8- url(r'^metadata', include('metadataserver.urls')),
9+ url(r'^metadata/', include('metadataserver.urls')),
10 )
11
12 if settings.STATIC_LOCAL_SERVE:
13
14=== modified file 'src/metadataserver/tests/test_api.py'
15--- src/metadataserver/tests/test_api.py 2012-06-20 16:33:18 +0000
16+++ src/metadataserver/tests/test_api.py 2012-06-20 16:33:18 +0000
17@@ -18,6 +18,7 @@
18
19 from django.conf import settings
20 from django.core.exceptions import PermissionDenied
21+from django.core.urlresolvers import reverse
22 from maasserver.enum import NODE_STATUS
23 from maasserver.exceptions import (
24 MAASAPINotFound,
25@@ -128,33 +129,6 @@
26 token = NodeKey.objects.get_token_for_node(node)
27 return OAuthAuthenticatedClient(get_node_init_user(), token)
28
29- def make_url(self, path):
30- """Create an absolute URL for `path` on the metadata API.
31-
32- :param path: Path within the metadata API to access. Should start
33- with a slash.
34- :return: An absolute URL for the given path within the metadata
35- service tree.
36- """
37- assert path.startswith('/'), "Give absolute metadata API path."
38- # Root of the metadata API service.
39- metadata_root = "/metadata"
40- return metadata_root + path
41-
42- def get(self, path, client=None):
43- """GET a resource from the metadata API.
44-
45- :param path: Path within the metadata API to access. Should start
46- with a slash.
47- :param token: If given, authenticate the request using this token.
48- :type token: oauth.oauth.OAuthToken
49- :return: A response to the GET request.
50- :rtype: django.http.HttpResponse
51- """
52- if client is None:
53- client = self.client
54- return client.get(self.make_url(path))
55-
56 def call_signal(self, client=None, version='latest', files={}, **kwargs):
57 """Call the API's signal method.
58
59@@ -177,37 +151,43 @@
60 for name, content in files.items():
61 params[name] = BytesIO(content)
62 params[name].name = name
63- return client.post(self.make_url('/%s/' % version), params)
64+ url = reverse('metadata-version', args=[version])
65+ return client.post(url, params)
66
67 def test_no_anonymous_access(self):
68- self.assertEqual(httplib.UNAUTHORIZED, self.get('/').status_code)
69+ self.assertEqual(
70+ httplib.UNAUTHORIZED,
71+ self.client.get(reverse('metadata')).status_code)
72
73 def test_metadata_index_shows_latest(self):
74 client = self.make_node_client()
75- self.assertIn('latest', self.get('/', client).content)
76+ self.assertIn('latest', client.get(reverse('metadata')).content)
77
78 def test_metadata_index_shows_only_known_versions(self):
79 client = self.make_node_client()
80- for item in self.get('/', client).content.splitlines():
81+ for item in client.get(reverse('metadata')).content.splitlines():
82 check_version(item)
83 # The test is that we get here without exception.
84 pass
85
86 def test_version_index_shows_meta_data(self):
87 client = self.make_node_client()
88- items = self.get('/latest/', client).content.splitlines()
89+ url = reverse('metadata-version', args=['latest'])
90+ items = client.get(url).content.splitlines()
91 self.assertIn('meta-data', items)
92
93 def test_version_index_does_not_show_user_data_if_not_available(self):
94 client = self.make_node_client()
95- items = self.get('/latest/', client).content.splitlines()
96+ url = reverse('metadata-version', args=['latest'])
97+ items = client.get(url).content.splitlines()
98 self.assertNotIn('user-data', items)
99
100 def test_version_index_shows_user_data_if_available(self):
101 node = factory.make_node()
102 NodeUserData.objects.set_user_data(node, b"User data for node")
103 client = self.make_node_client(node)
104- items = self.get('/latest/', client).content.splitlines()
105+ url = reverse('metadata-version', args=['latest'])
106+ items = client.get(url).content.splitlines()
107 self.assertIn('user-data', items)
108
109 def test_meta_data_view_lists_fields(self):
110@@ -215,20 +195,23 @@
111 user, _ = factory.make_user_with_keys(n_keys=2, username='my-user')
112 node = factory.make_node(owner=user)
113 client = self.make_node_client(node=node)
114- response = self.get('/latest/meta-data/', client)
115+ url = reverse('metadata-meta-data', args=['latest', ''])
116+ response = client.get(url)
117 self.assertIn('text/plain', response['Content-Type'])
118 self.assertItemsEqual(
119 MetaDataHandler.fields, response.content.split())
120
121 def test_meta_data_view_is_sorted(self):
122 client = self.make_node_client()
123- response = self.get('/latest/meta-data/', client)
124+ url = reverse('metadata-meta-data', args=['latest', ''])
125+ response = client.get(url)
126 attributes = response.content.split()
127 self.assertEqual(sorted(attributes), attributes)
128
129 def test_meta_data_unknown_item_is_not_found(self):
130 client = self.make_node_client()
131- response = self.get('/latest/meta-data/UNKNOWN-ITEM-HA-HA-HA', client)
132+ url = reverse('metadata-meta-data', args=['latest', 'UNKNOWN-ITEM'])
133+ response = client.get(url)
134 self.assertEqual(httplib.NOT_FOUND, response.status_code)
135
136 def test_get_attribute_producer_supports_all_fields(self):
137@@ -239,7 +222,8 @@
138 def test_meta_data_local_hostname_returns_hostname(self):
139 hostname = factory.getRandomString()
140 client = self.make_node_client(factory.make_node(hostname=hostname))
141- response = self.get('/latest/meta-data/local-hostname', client)
142+ url = reverse('metadata-meta-data', args=['latest', 'local-hostname'])
143+ response = client.get(url)
144 self.assertEqual(
145 (httplib.OK, hostname),
146 (response.status_code, response.content.decode('ascii')))
147@@ -248,7 +232,8 @@
148 def test_meta_data_instance_id_returns_system_id(self):
149 node = factory.make_node()
150 client = self.make_node_client(node)
151- response = self.get('/latest/meta-data/instance-id', client)
152+ url = reverse('metadata-meta-data', args=['latest', 'instance-id'])
153+ response = client.get(url)
154 self.assertEqual(
155 (httplib.OK, node.system_id),
156 (response.status_code, response.content.decode('ascii')))
157@@ -259,39 +244,45 @@
158 node = factory.make_node()
159 NodeUserData.objects.set_user_data(node, data)
160 client = self.make_node_client(node)
161- response = self.get('/latest/user-data', client)
162+ response = client.get(reverse('metadata-user-data', args=['latest']))
163 self.assertEqual('application/octet-stream', response['Content-Type'])
164 self.assertIsInstance(response.content, str)
165 self.assertEqual(
166 (httplib.OK, data), (response.status_code, response.content))
167
168 def test_user_data_for_node_without_user_data_returns_not_found(self):
169- response = self.get('/latest/user-data', self.make_node_client())
170+ client = self.make_node_client()
171+ response = client.get(reverse('metadata-user-data', args=['latest']))
172 self.assertEqual(httplib.NOT_FOUND, response.status_code)
173
174 def test_public_keys_not_listed_for_node_without_public_keys(self):
175- response = self.get('/latest/meta-data/', self.make_node_client())
176+ url = reverse('metadata-meta-data', args=['latest', ''])
177+ client = self.make_node_client()
178+ response = client.get(url)
179 self.assertNotIn(
180 'public-keys', response.content.decode('ascii').split('\n'))
181
182 def test_public_keys_listed_for_node_with_public_keys(self):
183 user, _ = factory.make_user_with_keys(n_keys=2, username='my-user')
184 node = factory.make_node(owner=user)
185- response = self.get(
186- '/latest/meta-data/', self.make_node_client(node=node))
187+ url = reverse('metadata-meta-data', args=['latest', ''])
188+ client = self.make_node_client(node=node)
189+ response = client.get(url)
190 self.assertIn(
191 'public-keys', response.content.decode('ascii').split('\n'))
192
193 def test_public_keys_for_node_without_public_keys_returns_not_found(self):
194- response = self.get(
195- '/latest/meta-data/public-keys', self.make_node_client())
196+ url = reverse('metadata-meta-data', args=['latest', 'public-keys'])
197+ client = self.make_node_client()
198+ response = client.get(url)
199 self.assertEqual(httplib.NOT_FOUND, response.status_code)
200
201 def test_public_keys_for_node_returns_list_of_keys(self):
202 user, _ = factory.make_user_with_keys(n_keys=2, username='my-user')
203 node = factory.make_node(owner=user)
204- response = self.get(
205- '/latest/meta-data/public-keys', self.make_node_client(node=node))
206+ url = reverse('metadata-meta-data', args=['latest', 'public-keys'])
207+ client = self.make_node_client(node=node)
208+ response = client.get(url)
209 self.assertEqual(httplib.OK, response.status_code)
210 keys = SSHKey.objects.filter(user=user).values_list('key', flat=True)
211 expected_response = '\n'.join(keys)
212@@ -320,7 +311,8 @@
213 def test_signaling_requires_status_code(self):
214 node = factory.make_node(status=NODE_STATUS.COMMISSIONING)
215 client = self.make_node_client(node=node)
216- response = client.post(self.make_url('/latest/'), {'op': 'signal'})
217+ url = reverse('metadata-version', args=['latest'])
218+ response = client.post(url, {'op': 'signal'})
219 self.assertEqual(httplib.BAD_REQUEST, response.status_code)
220
221 def test_signaling_rejects_unknown_status_code(self):
222@@ -505,8 +497,10 @@
223
224 def test_api_retrieves_node_metadata_by_mac(self):
225 mac = factory.make_mac_address()
226- response = self.get(
227- '/latest/by-mac/%s/meta-data/instance-id/' % mac.mac_address)
228+ url = reverse(
229+ 'metadata-meta-data-by-mac',
230+ args=['latest', mac.mac_address, 'instance-id'])
231+ response = self.client.get(url)
232 self.assertEqual(
233 (httplib.OK, mac.node.system_id),
234 (response.status_code, response.content))
235@@ -515,7 +509,9 @@
236 mac = factory.make_mac_address()
237 user_data = factory.getRandomString().encode('ascii')
238 NodeUserData.objects.set_user_data(mac.node, user_data)
239- response = self.get('/latest/by-mac/%s/user-data' % mac.mac_address)
240+ url = reverse(
241+ 'metadata-user-data-by-mac', args=['latest', mac.mac_address])
242+ response = self.client.get(url)
243 self.assertEqual(
244 (httplib.OK, user_data),
245 (response.status_code, response.content))
246@@ -523,29 +519,33 @@
247 def test_api_normally_disallows_anonymous_node_metadata_access(self):
248 self.patch(settings, 'ALLOW_ANONYMOUS_METADATA_ACCESS', False)
249 mac = factory.make_mac_address()
250- response = self.get(
251- '/latest/by-mac/%s/meta-data/instance-id/' % mac.mac_address)
252+ url = reverse(
253+ 'metadata-meta-data-by-mac',
254+ args=['latest', mac.mac_address, 'instance-id'])
255+ response = self.client.get(url)
256 self.assertEqual(httplib.FORBIDDEN, response.status_code)
257
258 def test_netboot_off(self):
259 node = factory.make_node(netboot=True)
260 client = self.make_node_client(node=node)
261- response = client.post(
262- self.make_url('/latest/'), {'op': 'netboot_off'})
263+ url = reverse('metadata-version', args=['latest'])
264+ response = client.post(url, {'op': 'netboot_off'})
265 node = reload_object(node)
266 self.assertFalse(node.netboot, response)
267
268 def test_netboot_on(self):
269 node = factory.make_node(netboot=False)
270 client = self.make_node_client(node=node)
271- response = client.post(self.make_url('/latest/'), {'op': 'netboot_on'})
272+ url = reverse('metadata-version', args=['latest'])
273+ response = client.post(url, {'op': 'netboot_on'})
274 node = reload_object(node)
275 self.assertTrue(node.netboot, response)
276
277 def test_anonymous_netboot_off(self):
278 node = factory.make_node(netboot=True)
279- anon_netboot_off_url = self.make_url(
280- '/latest/%s/edit/' % node.system_id)
281+ anon_netboot_off_url = reverse(
282+ 'metadata-anon-node-edit', args=['latest',
283+ node.system_id])
284 response = self.client.post(
285 anon_netboot_off_url, {'op': 'netboot_off'})
286 node = reload_object(node)