Merge lp:~devcamcar/django-nova/improve_unittests into lp:django-nova

Proposed by Devin Carlen
Status: Merged
Approved by: Devin Carlen
Approved revision: 21
Merged at revision: 16
Proposed branch: lp:~devcamcar/django-nova/improve_unittests
Merge into: lp:django-nova
Diff against target: 615 lines (+427/-29)
11 files modified
src/django_nova/tests/urls.py (+5/-1)
src/django_nova/tests/view_tests/__init__.py (+6/-2)
src/django_nova/tests/view_tests/base.py (+54/-15)
src/django_nova/tests/view_tests/credential_tests.py (+70/-0)
src/django_nova/tests/view_tests/image_tests.py (+22/-0)
src/django_nova/tests/view_tests/instance_tests.py (+22/-0)
src/django_nova/tests/view_tests/keypair_tests.py (+25/-3)
src/django_nova/tests/view_tests/region_tests.py (+43/-0)
src/django_nova/tests/view_tests/volume_tests.py (+170/-0)
src/django_nova/views/credentials.py (+4/-2)
src/django_nova/views/volumes.py (+6/-6)
To merge this branch: bzr merge lp:~devcamcar/django-nova/improve_unittests
Reviewer Review Type Date Requested Status
Devin Carlen Approve
Review via email: mp+49529@code.launchpad.net

Description of the change

Improved unit tests for views

To post a comment you must log in.
Revision history for this message
Devin Carlen (devcamcar) wrote :

approve

review: Approve
Revision history for this message
Jesse Andrews (anotherjesse) wrote :

u can do merge?

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/django_nova/tests/urls.py'
--- src/django_nova/tests/urls.py 2011-01-18 02:09:01 +0000
+++ src/django_nova/tests/urls.py 2011-02-13 02:22:10 +0000
@@ -29,4 +29,8 @@
29 url(r'^region/', include('django_nova.urls.region')),29 url(r'^region/', include('django_nova.urls.region')),
30 url(r'^admin/projects/', include('django_nova.urls.admin_project')),30 url(r'^admin/projects/', include('django_nova.urls.admin_project')),
31 url(r'^admin/roles/', include('django_nova.urls.admin_roles')),31 url(r'^admin/roles/', include('django_nova.urls.admin_roles')),
32)
33\ No newline at end of file32\ No newline at end of file
33 url(r'^credentials/download/(?P<auth_token>\w+)/$',
34 'django_nova.views.credentials.authorize_credentials',
35 name='nova_credentials_authorize'),
36)
37
3438
=== modified file 'src/django_nova/tests/view_tests/__init__.py'
--- src/django_nova/tests/view_tests/__init__.py 2011-01-21 22:38:42 +0000
+++ src/django_nova/tests/view_tests/__init__.py 2011-02-13 02:22:10 +0000
@@ -1,3 +1,7 @@
1from credential_tests import *
2from image_tests import *
3from instance_tests import *
1from keypair_tests import *4from keypair_tests import *
2from image_tests import *
3from instance_tests import *
4\ No newline at end of file5\ No newline at end of file
6from region_tests import *
7from volume_tests import *
8
59
=== modified file 'src/django_nova/tests/view_tests/base.py'
--- src/django_nova/tests/view_tests/base.py 2011-01-22 22:27:53 +0000
+++ src/django_nova/tests/view_tests/base.py 2011-02-13 02:22:10 +0000
@@ -1,3 +1,25 @@
1# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2010 United States Government as represented by the
4# Administrator of the National Aeronautics and Space Administration.
5# All Rights Reserved.
6#
7# Licensed under the Apache License, Version 2.0 (the "License"); you may
8# not use this file except in compliance with the License. You may obtain
9# a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16# License for the specific language governing permissions and limitations
17# under the License.
18
19"""
20Base classes for view based unit tests.
21"""
22
1import mox23import mox
224
3from django import test25from django import test
@@ -13,19 +35,36 @@
13TEST_REGION = 'test'35TEST_REGION = 'test'
1436
1537
16class BaseProjectViewTests(test.TestCase):38class BaseViewTests(test.TestCase):
17 def setUp(self):39 def setUp(self):
18 project = adminclient.ProjectInfo()
19 project.projectname = TEST_PROJECT
20 project.projectManagerId = TEST_USER
21
22 self.mox = mox.Mox()40 self.mox = mox.Mox()
23 self.user = auth_models.User.objects.create_user(TEST_USER,41
42 def tearDown(self):
43 self.mox.UnsetStubs()
44
45 def assertRedirectsNoFollow(self, response, expected_url):
46 self.assertEqual(response._headers['location'],
47 ('Location', settings.TESTSERVER + expected_url))
48 self.assertEqual(response.status_code, 302)
49
50 def authenticateTestUser(self):
51 user = auth_models.User.objects.create_user(TEST_USER,
24 'test@test.com',52 'test@test.com',
25 password='test')53 password='test')
26 login = self.client.login(username=TEST_USER, password='test')54 login = self.client.login(username=TEST_USER, password='test')
27 self.failUnless(login, 'Unable to login')55 self.failUnless(login, 'Unable to login')
2856 return user
57
58
59class BaseProjectViewTests(BaseViewTests):
60 def setUp(self):
61 super(BaseProjectViewTests, self).setUp()
62
63 project = adminclient.ProjectInfo()
64 project.projectname = TEST_PROJECT
65 project.projectManagerId = TEST_USER
66
67 self.user = self.authenticateTestUser()
29 self.region = adminclient.RegionInfo(name=TEST_REGION,68 self.region = adminclient.RegionInfo(name=TEST_REGION,
30 endpoint='http://test:8773/')69 endpoint='http://test:8773/')
31 self.project = manager.ProjectManager(self.user.username,70 self.project = manager.ProjectManager(self.user.username,
@@ -35,17 +74,17 @@
35 shortcuts.get_project_or_404(mox.IgnoreArg(),74 shortcuts.get_project_or_404(mox.IgnoreArg(),
36 'test').AndReturn(self.project)75 'test').AndReturn(self.project)
3776
38 def tearDown(self):
39 self.mox.UnsetStubs()
40
41 def assertRedirectsNoFollow(self, response, expected_url):
42 self.assertEqual(response._headers['location'],
43 ('Location', settings.TESTSERVER + expected_url))
44 self.assertEqual(response.status_code, 302)
45
46 def create_key_pair_choices(self, key_names):77 def create_key_pair_choices(self, key_names):
47 return [(k, k) for k in key_names]78 return [(k, k) for k in key_names]
4879
49 def create_instance_type_choices(self):80 def create_instance_type_choices(self):
50 return [('m1.medium', 'm1.medium'),81 return [('m1.medium', 'm1.medium'),
51 ('m1.large', 'm1.large')]82 ('m1.large', 'm1.large')]
83
84 def create_instance_choices(self, instance_ids):
85 return [(id, id) for id in instance_ids]
86
87 def create_available_volume_choices(self, volumes):
88 return [(v.id, '%s %s - %dGB' % (v.id, v.displayName, v.size)) \
89 for v in volumes]
90
5291
=== added file 'src/django_nova/tests/view_tests/credential_tests.py'
--- src/django_nova/tests/view_tests/credential_tests.py 1970-01-01 00:00:00 +0000
+++ src/django_nova/tests/view_tests/credential_tests.py 2011-02-13 02:22:10 +0000
@@ -0,0 +1,70 @@
1# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2010 United States Government as represented by the
4# Administrator of the National Aeronautics and Space Administration.
5# All Rights Reserved.
6#
7# Licensed under the Apache License, Version 2.0 (the "License"); you may
8# not use this file except in compliance with the License. You may obtain
9# a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16# License for the specific language governing permissions and limitations
17# under the License.
18
19"""
20Unit tests for credential views.
21"""
22
23import mox
24from django.conf import settings
25from django.core.urlresolvers import reverse
26from django_nova import models
27from django_nova.tests.view_tests.base import BaseViewTests
28
29
30class CredentialViewTests(BaseViewTests):
31 def test_download_expired_credentials(self):
32 auth_token = 'expired'
33 self.mox.StubOutWithMock(models.CredentialsAuthorization,
34 'get_by_token')
35 models.CredentialsAuthorization.get_by_token(auth_token) \
36 .AndReturn(None)
37 self.mox.ReplayAll()
38
39 res = self.client.get(reverse('nova_credentials_authorize',
40 args=[auth_token]))
41 self.assertTemplateUsed(res, 'django_nova/credentials/expired.html')
42
43 self.mox.VerifyAll()
44
45 def test_download_good_credentials(self):
46 auth_token = 'good'
47
48 creds = models.CredentialsAuthorization()
49 creds.username = 'test'
50 creds.project = 'test'
51 creds.auth_token = auth_token
52
53 self.mox.StubOutWithMock(models.CredentialsAuthorization,
54 'get_by_token')
55 self.mox.StubOutWithMock(creds, 'get_zip')
56 models.CredentialsAuthorization.get_by_token(auth_token) \
57 .AndReturn(creds)
58 creds.get_zip().AndReturn('zip')
59
60 self.mox.ReplayAll()
61
62 res = self.client.get(reverse('nova_credentials_authorize',
63 args=[auth_token]))
64 self.assertEqual(res.status_code, 200)
65 self.assertEqual(res['Content-Disposition'],
66 'attachment; filename=%s-test-test-x509.zip' %
67 settings.SITE_NAME)
68 self.assertContains(res, 'zip')
69
70 self.mox.VerifyAll()
071
=== modified file 'src/django_nova/tests/view_tests/image_tests.py'
--- src/django_nova/tests/view_tests/image_tests.py 2011-01-25 23:51:20 +0000
+++ src/django_nova/tests/view_tests/image_tests.py 2011-02-13 02:22:10 +0000
@@ -1,3 +1,25 @@
1# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2010 United States Government as represented by the
4# Administrator of the National Aeronautics and Space Administration.
5# All Rights Reserved.
6#
7# Licensed under the Apache License, Version 2.0 (the "License"); you may
8# not use this file except in compliance with the License. You may obtain
9# a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16# License for the specific language governing permissions and limitations
17# under the License.
18
19"""
20Unit tests for image views.
21"""
22
1import boto.ec2.image23import boto.ec2.image
2import boto.ec2.instance24import boto.ec2.instance
3import mox25import mox
426
=== modified file 'src/django_nova/tests/view_tests/instance_tests.py'
--- src/django_nova/tests/view_tests/instance_tests.py 2011-01-22 01:04:51 +0000
+++ src/django_nova/tests/view_tests/instance_tests.py 2011-02-13 02:22:10 +0000
@@ -1,3 +1,25 @@
1# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2010 United States Government as represented by the
4# Administrator of the National Aeronautics and Space Administration.
5# All Rights Reserved.
6#
7# Licensed under the Apache License, Version 2.0 (the "License"); you may
8# not use this file except in compliance with the License. You may obtain
9# a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16# License for the specific language governing permissions and limitations
17# under the License.
18
19"""
20Unit tests for instance views.
21"""
22
1import boto.ec2.instance23import boto.ec2.instance
2import mox24import mox
325
426
=== modified file 'src/django_nova/tests/view_tests/keypair_tests.py'
--- src/django_nova/tests/view_tests/keypair_tests.py 2011-01-22 01:04:51 +0000
+++ src/django_nova/tests/view_tests/keypair_tests.py 2011-02-13 02:22:10 +0000
@@ -1,8 +1,31 @@
1# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2010 United States Government as represented by the
4# Administrator of the National Aeronautics and Space Administration.
5# All Rights Reserved.
6#
7# Licensed under the Apache License, Version 2.0 (the "License"); you may
8# not use this file except in compliance with the License. You may obtain
9# a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16# License for the specific language governing permissions and limitations
17# under the License.
18
19"""
20Unit tests for key pair views.
21"""
22
1import boto.ec2.keypair23import boto.ec2.keypair
2import mox24import mox
325
4from django.core.urlresolvers import reverse26from django.core.urlresolvers import reverse
5from django_nova.tests.view_tests.base import BaseProjectViewTests, TEST_PROJECT27from django_nova.tests.view_tests.base import (BaseProjectViewTests,
28 TEST_PROJECT)
629
730
8TEST_KEY = 'test_key'31TEST_KEY = 'test_key'
@@ -36,8 +59,7 @@
3659
37 url = reverse('nova_keypairs_add', args=[TEST_PROJECT])60 url = reverse('nova_keypairs_add', args=[TEST_PROJECT])
38 data = {'js': '0', 'name': key.name}61 data = {'js': '0', 'name': key.name}
39 res = self.client.post(url,62 res = self.client.post(url, data)
40 data)
41 self.assertEqual(res.status_code, 200)63 self.assertEqual(res.status_code, 200)
42 self.assertEqual(res['Content-Type'], 'application/binary')64 self.assertEqual(res['Content-Type'], 'application/binary')
4365
4466
=== added file 'src/django_nova/tests/view_tests/region_tests.py'
--- src/django_nova/tests/view_tests/region_tests.py 1970-01-01 00:00:00 +0000
+++ src/django_nova/tests/view_tests/region_tests.py 2011-02-13 02:22:10 +0000
@@ -0,0 +1,43 @@
1# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2010 United States Government as represented by the
4# Administrator of the National Aeronautics and Space Administration.
5# All Rights Reserved.
6#
7# Licensed under the Apache License, Version 2.0 (the "License"); you may
8# not use this file except in compliance with the License. You may obtain
9# a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16# License for the specific language governing permissions and limitations
17# under the License.
18
19"""
20Unit tests for region views.
21"""
22
23from django.core.urlresolvers import reverse
24from django_nova.tests.view_tests.base import BaseViewTests
25from django_nova import shortcuts
26
27
28TEST_REGION = 'one'
29
30
31class RegionViewTests(BaseViewTests):
32 def test_change(self):
33 self.authenticateTestUser()
34 session = self.client.session
35 session['region'] = 'two'
36 session.save()
37
38 data = {'redirect_url': '/',
39 'region': TEST_REGION}
40 res = self.client.post(reverse('region_change'), data)
41 self.assertEqual(self.client.session['region'], TEST_REGION)
42 self.assertRedirectsNoFollow(res, '/')
43
044
=== added file 'src/django_nova/tests/view_tests/volume_tests.py'
--- src/django_nova/tests/view_tests/volume_tests.py 1970-01-01 00:00:00 +0000
+++ src/django_nova/tests/view_tests/volume_tests.py 2011-02-13 02:22:10 +0000
@@ -0,0 +1,170 @@
1# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2010 United States Government as represented by the
4# Administrator of the National Aeronautics and Space Administration.
5# All Rights Reserved.
6#
7# Licensed under the Apache License, Version 2.0 (the "License"); you may
8# not use this file except in compliance with the License. You may obtain
9# a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16# License for the specific language governing permissions and limitations
17# under the License.
18
19"""
20Unit tests for volume views.
21"""
22
23import boto.ec2.volume
24import mox
25
26from django.core.urlresolvers import reverse
27from django_nova import forms
28from django_nova.tests.view_tests.base import (BaseProjectViewTests,
29 TEST_PROJECT)
30
31
32TEST_VOLUME = 'vol-0000001'
33
34
35class VolumeTests(BaseProjectViewTests):
36 def test_index(self):
37 instance_id = 'i-abcdefgh'
38
39 volume = boto.ec2.volume.Volume()
40 volume.id = TEST_VOLUME
41 volume.displayName = TEST_VOLUME
42 volume.size = 1
43
44 self.mox.StubOutWithMock(self.project, 'get_volumes')
45 self.mox.StubOutWithMock(forms, 'get_available_volume_choices')
46 self.mox.StubOutWithMock(forms, 'get_instance_choices')
47 self.project.get_volumes().AndReturn([])
48 forms.get_available_volume_choices(mox.IgnoreArg()).AndReturn(
49 self.create_available_volume_choices([volume]))
50 forms.get_instance_choices(mox.IgnoreArg()).AndReturn(
51 self.create_instance_choices([instance_id]))
52
53 self.mox.ReplayAll()
54
55 response = self.client.get(reverse('nova_volumes',
56 args=[TEST_PROJECT]))
57 self.assertEqual(response.status_code, 200)
58 self.assertTemplateUsed(response, 'django_nova/volumes/index.html')
59 self.assertEqual(len(response.context['volumes']), 0)
60
61 self.mox.VerifyAll()
62
63 def test_add_get(self):
64 self.mox.ReplayAll()
65
66 res = self.client.get(reverse('nova_volumes_add', args=[TEST_PROJECT]))
67 self.assertRedirectsNoFollow(res, reverse('nova_volumes',
68 args=[TEST_PROJECT]))
69 self.mox.VerifyAll()
70
71 def test_add_post(self):
72 vol = boto.ec2.volume.Volume()
73 vol.name = TEST_VOLUME
74 vol.displayName = TEST_VOLUME
75 vol.size = 1
76
77 self.mox.StubOutWithMock(self.project, 'create_volume')
78 self.project.create_volume(vol.size, vol.name, vol.name).AndReturn(vol)
79
80 self.mox.ReplayAll()
81
82 url = reverse('nova_volumes_add', args=[TEST_PROJECT])
83 data = {'size': '1',
84 'nickname': TEST_VOLUME,
85 'description': TEST_VOLUME}
86 res = self.client.post(url, data)
87 self.assertRedirectsNoFollow(res, reverse('nova_volumes',
88 args=[TEST_PROJECT]))
89 self.mox.VerifyAll()
90
91 def test_delete_get(self):
92 self.mox.ReplayAll()
93
94 res = self.client.get(reverse('nova_volumes_delete',
95 args=[TEST_PROJECT, TEST_VOLUME]))
96 self.assertRedirectsNoFollow(res, reverse('nova_volumes',
97 args=[TEST_PROJECT]))
98 self.mox.VerifyAll()
99
100 def test_delete_post(self):
101 self.mox.StubOutWithMock(self.project, 'delete_volume')
102 self.project.delete_volume(TEST_VOLUME).AndReturn(True)
103
104 self.mox.ReplayAll()
105
106 res = self.client.post(reverse('nova_volumes_delete',
107 args=[TEST_PROJECT, TEST_VOLUME]))
108 self.assertRedirectsNoFollow(res, reverse('nova_volumes',
109 args=[TEST_PROJECT]))
110 self.mox.VerifyAll()
111
112 def test_attach_get(self):
113 self.mox.ReplayAll()
114
115 res = self.client.get(reverse('nova_volumes_attach',
116 args=[TEST_PROJECT]))
117 self.assertRedirectsNoFollow(res, reverse('nova_volumes',
118 args=[TEST_PROJECT]))
119 self.mox.VerifyAll()
120
121 def test_attach_post(self):
122 volume = boto.ec2.volume.Volume()
123 volume.id = TEST_VOLUME
124 volume.displayName = TEST_VOLUME
125 volume.size = 1
126
127 instance_id = 'i-abcdefgh'
128 device = '/dev/vdb'
129
130 self.mox.StubOutWithMock(self.project, 'attach_volume')
131 self.mox.StubOutWithMock(forms, 'get_available_volume_choices')
132 self.mox.StubOutWithMock(forms, 'get_instance_choices')
133 self.project.attach_volume(TEST_VOLUME, instance_id, device) \
134 .AndReturn(True)
135 forms.get_available_volume_choices(mox.IgnoreArg()).AndReturn(
136 self.create_available_volume_choices([volume]))
137 forms.get_instance_choices(mox.IgnoreArg()).AndReturn(
138 self.create_instance_choices([instance_id]))
139
140 self.mox.ReplayAll()
141
142 url = reverse('nova_volumes_attach', args=[TEST_PROJECT])
143 data = {'volume': TEST_VOLUME,
144 'instance': instance_id,
145 'device': device}
146 res = self.client.post(url, data)
147 self.assertRedirectsNoFollow(res, reverse('nova_volumes',
148 args=[TEST_PROJECT]))
149 self.mox.VerifyAll()
150
151 def test_detach_get(self):
152 self.mox.ReplayAll()
153
154 res = self.client.get(reverse('nova_volumes_detach',
155 args=[TEST_PROJECT, TEST_VOLUME]))
156 self.assertRedirectsNoFollow(res, reverse('nova_volumes',
157 args=[TEST_PROJECT]))
158 self.mox.VerifyAll()
159
160 def test_detach_post(self):
161 self.mox.StubOutWithMock(self.project, 'detach_volume')
162 self.project.detach_volume(TEST_VOLUME).AndReturn(True)
163
164 self.mox.ReplayAll()
165
166 res = self.client.post(reverse('nova_volumes_detach',
167 args=[TEST_PROJECT, TEST_VOLUME]))
168 self.assertRedirectsNoFollow(res, reverse('nova_volumes',
169 args=[TEST_PROJECT]))
170 self.mox.VerifyAll()
0171
=== modified file 'src/django_nova/views/credentials.py'
--- src/django_nova/views/credentials.py 2011-01-31 20:08:02 +0000
+++ src/django_nova/views/credentials.py 2011-02-13 02:22:10 +0000
@@ -17,7 +17,8 @@
17# under the License.17# under the License.
1818
19"""19"""
20Views for downloading X509 credentials.20Views for downloading X509 credentials. Useful when using an invitation
21style system for configuring first time users.
21"""22"""
2223
23from django import http24from django import http
@@ -26,7 +27,8 @@
26from django_nova import models27from django_nova import models
2728
2829
29def download_credentials(request, auth_token):30def authorize_credentials(request, auth_token):
31 """Sends X509 credentials to user if their auth token is valid."""
30 auth_token = auth_token.lower()32 auth_token = auth_token.lower()
31 credentials = models.CredentialsAuthorization.get_by_token(auth_token)33 credentials = models.CredentialsAuthorization.get_by_token(auth_token)
3234
3335
=== modified file 'src/django_nova/views/volumes.py'
--- src/django_nova/views/volumes.py 2011-01-25 23:16:49 +0000
+++ src/django_nova/views/volumes.py 2011-02-13 02:22:10 +0000
@@ -26,14 +26,14 @@
26from django.shortcuts import redirect, render_to_response26from django.shortcuts import redirect, render_to_response
27from django_nova import exceptions27from django_nova import exceptions
28from django_nova import forms28from django_nova import forms
29from django_nova import shortcuts
29from django_nova.exceptions import handle_nova_error30from django_nova.exceptions import handle_nova_error
30from django_nova.shortcuts import get_project_or_404
3131
3232
33@login_required33@login_required
34@handle_nova_error34@handle_nova_error
35def index(request, project_id):35def index(request, project_id):
36 project = get_project_or_404(request, project_id)36 project = shortcuts.get_project_or_404(request, project_id)
37 volumes = project.get_volumes()37 volumes = project.get_volumes()
3838
39 return render_to_response('django_nova/volumes/index.html', {39 return render_to_response('django_nova/volumes/index.html', {
@@ -48,7 +48,7 @@
48@login_required48@login_required
49@handle_nova_error49@handle_nova_error
50def add(request, project_id):50def add(request, project_id):
51 project = get_project_or_404(request, project_id)51 project = shortcuts.get_project_or_404(request, project_id)
5252
53 if request.method == 'POST':53 if request.method == 'POST':
54 form = forms.CreateVolumeForm(request.POST)54 form = forms.CreateVolumeForm(request.POST)
@@ -81,7 +81,7 @@
81@login_required81@login_required
82@handle_nova_error82@handle_nova_error
83def delete(request, project_id, volume_id):83def delete(request, project_id, volume_id):
84 project = get_project_or_404(request, project_id)84 project = shortcuts.get_project_or_404(request, project_id)
8585
86 if request.method == 'POST':86 if request.method == 'POST':
87 try:87 try:
@@ -100,7 +100,7 @@
100@login_required100@login_required
101@handle_nova_error101@handle_nova_error
102def attach(request, project_id):102def attach(request, project_id):
103 project = get_project_or_404(request, project_id)103 project = shortcuts.get_project_or_404(request, project_id)
104104
105 if request.method == 'POST':105 if request.method == 'POST':
106 form = forms.AttachVolumeForm(project, request.POST)106 form = forms.AttachVolumeForm(project, request.POST)
@@ -135,7 +135,7 @@
135@login_required135@login_required
136@handle_nova_error136@handle_nova_error
137def detach(request, project_id, volume_id):137def detach(request, project_id, volume_id):
138 project = get_project_or_404(request, project_id)138 project = shortcuts.get_project_or_404(request, project_id)
139139
140 if request.method == 'POST':140 if request.method == 'POST':
141 try:141 try:

Subscribers

People subscribed via source and target branches

to all changes:
to status/vote changes: